why not

Dutch pay 서비스에서 이용할 기술셋 7 (28일차) 본문

Today I Learn/환급 챌린지

Dutch pay 서비스에서 이용할 기술셋 7 (28일차)

novem 2023. 3. 19. 09:00

<Jest >

1. Jest?

  • 프론트엔드 어플리케이션을 쉽게 테스팅 할 수 있도록 다양한 인터페이스를 제공하는 Javsacript용 테스팅 프레임워크
  • 메타(전 Facebook)에서 만들고, 오픈소스로 배포
  • 문서화가 아주 잘 되어 있다.
  • 직관적이다.

2. Jest가 주고자 하는 가치와 철학

  • Jest is a delightful JavaScript Testing Framework with a focus on simplicity

3. 특징

3-1. 고립됨(isolated)

  • 각 테스트 케이스는 고립된 환경에서 돌아감
  • 고립되었기 때문에, 테스트 성능을 최대화 시키기 위해 여러 테스트 케이스들을 병렬적으로 돌리는 것도 가능하다.

3-2. 쉬운 설치 및 시작

  • Jest 내에 테스트 러너(runner), 확인(assertion), 코드 커버리지 등 테스팅에 필요한 거의 대부분의 기능들을 이미 지원해서 테스팅을 위해 별도로 다른 툴을 설치하지 않아도 됨
  • Zero-config! 패키지를 설치 후, 별도의 설정 없이 빠르게 테스트 가능
  • {fileName}.spec.js 형식만 따르면 바로 테스트 실행 가능

3-3. 스냅샷(snapshot)

  • 객체 내부의 당시의 상태나 값을 스냅샷으로 파일에 저장해두는 것을 의미함
  • 보통 리액트의 가상 DOM 트리 구조를 비교하기 위해 사용됨
  • 다음 테스트에서 객체의 현재 상태가 스냅샷과 동일한지 아닌지 테스팅 하기도 함
  • 위 테스트가 처음 돌아가면, 스냅샷 파일이 jest에 의해 아래와 같이 자동으로 생성됨
/* snapshot */
export [`renders correctly 1`] =`
<a
	className= normal"
	herf="http://www.facebook.com"
	onMouseEnter={[function]}
	onMouseLeave={[function]}
>
	Facebook
</a>
`;

3-4. 테스트 셋 설정/분해(setup/teardown)

  • 테스트가 시작되기 전, 끝난 후에 일어나야 할 일들이 있다 (예를 들면, DB와의 커넥션 맺고 끊기, 데이터 리셋 등)

3-4.1) 테스트 단위마다 설정/분해가 일어나야 할 경우

  • beforeEach()
  • afterEach()
beforeEach{() => {
  setupDataSet()
}}

afterEach(() => {
  clearDataSet()
})

test('그룹을 생성한다', () => {...})
test('이름이 없는 경우, 그룹을 생성하지 않고 에러 메시지를 노출한다', () => {...})

3-4.2) 테스트 파일 내에서 한 번만 설정/분해가 일어나도 될 경우

  • beforeAll()
  • afterAll()
beforeAll{() => {
  connectDB()
}}

afterAll(() => {
  disconnectDB()
})

test('그룹을 생성한다', () => {...})
test('이름이 없는 경우, 그룹을 생성하지 않고 에러 메시지를 노출한다', () => {...})

4. 목(Mock) 함수

  • 조작된 값을 리턴하는 가짜 함수를 만드는 것. 이 테스트 코드 내에서 컨트롤 하기 어려운 것들(예를 들면 외부 API 값, 함수)을 이용해서 테스트 코드를 작성해야 할 때 사용함
  • jest.fn() 으로 목킹(mocking)을 할 수 있고, 목킹 된 함수가 호출될 경우 기본적으로 undefined를 리턴함
  • 어떤 값을 리턴할 것인지 설정도 가능
const mock = jest.fn()

mock.mockReturnValue(42)
console.log(mock()) // 42

mock.mockReturnValue(43)
console.log(mock()) // 43
  • 호출 될 때마다 각기 다른 값을 리턴 시킬 수도 있음
const mock = jest.fn()
				.mockReturnValue(0)
				.mockReturnValue(42)
				.mockReturnValue(43)


console.log(mock()) // 42
console.log(mock()) // 43
console.log(mock()) // 0
console.log(mock()) // 0
  • 비동기 함수도 목킹이 가능함
/* option 1*/
const mock = jest.fn().mockResolveValue(43);

console.log(await mock()) // 43

/* option 2*/
const mock = jest.fn().mockImplementation(() => Promise.resolve(43))

console.log(await mock2()) // 43
  • 모듈도 목킹이 가능! 해당 모듈에서 제공하는 API 들을 리턴해주면 된다.
beforeEach(() => {
  jest.resetModules();
});

test('moduleName 1', () => {
  jest.doMock('../moduleName', () => {
  return jest.fn(() => 1);
});

  const moduleName = require('../moduleName');
  expect(moduleName()).toEqual(1);
});

5. API

5-1. describe

  • describe(name, function)의 형태로, 관련된 테스트들을 한 데 묶어주는 블럭(block)이다.
  • 중첩이 가능하다.
describe('사용자가 로그인 하지 않았을 때' () => {
  describe('그룹 만들기 컴포넌트가 렌더링 됐을 때' () => {
    describe('이름 값을 입력하지 않은 경우 에러 메시지 노출' () => {...})
  })
})

5-2. test

  • 테스트의 최소 단위 (a.k.a. 하나의 테스트 케이스)
  • 이 테스트 함수 내에서, expect 구문을 활용하여 값을 검증한다.

5-3. expect

  • toBe(object) ↔ not.toBe(object)
  • toEqual(object) ↔ not.toEqual
  • toBeNull() ↔ not.toBeNull
  • toBeTruthy() ↔ toBeFalsy()
  • toContain(string) ↔ not.toContain
  • toGreaterThan(number) ↔ toLessOrEqualThan
  • toThrow(exception) ↔ not.toThrow
  • toMatch(regex expression) ↔ not.toMatch
test('이름 값을 입력하지 않은 경우 에러 메시지 노출', () => {
  ...
  expect(response.message).toEqual('이름 값을 입력해 주세요')
})

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

* 필수 삽입 링크 : http://bit.ly/3Y34pE0

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr