[Jest] Jest 시작하기

@1000peach2022. 05. 06  -  ☕️ 5 min read
[Jest] Jest 시작하기

1. Jest란?

  • 페이스북에서 만든 Javascript 테스팅 프레임워크
  • zero config 실현 : 별도 설정 없이 빠르게 테스트 케이스를 작성할 수 있는 장점이 있다.

2. 구성

새 프로젝트에서 jest와 typescript, es6 모듈 시스템을 사용할 수 있도록 설정한다.

2-1. 설치

yarn add --dev jest ts-jest @types/jest babel-jest @babel/core @babel/preset-env

2-2. 설정

babel.config.json

{ "presets": [["@babel/preset-env", { "targets": { "node": "current" } }]] }

jest.config.json

{ "collectCoverage": true, "moduleFileExtensions": ["js", "ts"], "testMatch": ["**/__tests__/**/*.+(ts|js)", "**/?(*.)+(spec|test).+(ts|js)"], "transform": { "^.+\\.(ts)$": "ts-jest" } }

package.json

{ ... "scripts": { "test": "jest" }, ... }

jest는 yarn test 실행 시 testMatch와 일치하는 모든 파일을 테스트 코드로 인식하여 테스트를 실행한다. 특정 파일만 테스트 하고 싶다면 yarn test 뒤에 파일명 또는 경로를 입력한다.


3. 시작하기

fn.ts

const fn = { add: (number1: number, number2: number) => number1 + number2, } export default fn

fn.test.ts

import fn from './fn' // 긍정 test('1 더하기 2는 3이다.', () => { expect(fn.add(1, 2)).toBe(3) }) test('0 더하기 1은 1이다.', () => { expect(fn.add(0, 1)).toBe(1) }) // 부정 test('3 더하기 3은 5가 아니다.', () => { expect(fn.add(3, 3)).not.toBe(5) })
  • test : 첫 번째 인수로 테스트 이름, 두 번째 인수로 테스트 함수, 세 번째 인수로 timeout 값을 넣는다.
테스트 결과에 어떤 테스트가 실패했는 지 이름을 통해 알 수 있으므로 쉽고 명확하게 작성해야 한다.

테스트 결과

  • expect : 검증할 값 / toBe : 기대하는 값
  • 매처(Matcher) : 기본형을 비교할 때 사용하며 여러가지 matcher가 있다. ex) toBe

4. 자주 사용하는 Matcher

4-1. toEqual

기본형에서는 toBe와 유사하게 동작한다.

// 둘 다 테스트 성공 test('0 더하기 1은 3입니다.', () => { expect(fn.add(0, 1)).toBe(1) }) test('0 더하기 1은 3입니다.', () => { expect(fn.add(0, 1)).toEqual(1) })

하지만 객체, 배열은 재귀적으로 돌며 값을 확인해야 하기 때문에 toBe로 사용할 수 없으며 toEqual로 비교해야 한다.

fn.ts

const fn = { add: (number1: number, number2: number) => number1 + number2, makeUser: (name: string, age: number) => ({ name, age }), // 이름과 나이를 객체로 반환하는 함수 추가 } export default fn

fn.test.ts

// 테스트 실패 test('이름과 나이를 입력받아 객체로 반환한다.', () => { expect(fn.makeUser('1000peach', 10)).toBe({ name: '1000peach', age: 10, }) }) // 테스트 성공 test('이름과 나이를 입력받아 객체로 반환한다.', () => { expect(fn.makeUser('1000peach', 10)).toEqual({ name: '1000peach', age: 10, }) })

4-1-1. toStrictEqual

보다 엄격하게 비교하려면 toStrictEqual을 사용한다.

fn.makeUser 함수에서 gender: undefined를 반환하게 되면 toEqualtoStrictEqual은 다른 결과를 보인다.

fn.ts

const fn = { add: (number1: number, number2: number) => number1 + number2, makeUser: (name: string, age: number) => ({ name, age, gender: undefined }), } export default fn // 테스트 성공 test('이름과 나이를 입력받아 객체로 반환한다.', () => { expect(fn.makeUser('1000peach', 10)).toEqual({ name: '1000peach', age: 10, }) }) // 테스트 실패 test('이름과 나이를 입력받아 객체로 반환한다.', () => { expect(fn.makeUser('1000peach', 10)).toStrictEqual({ name: '1000peach', age: 10, }) })

4-2. toBeNull, toBeUndefined, toBeDefined

  • 이름 그대로 null, undefined, defined인 경우 테스트를 통과한다.
// 테스트 성공 test('null은 null이다.', () => { expect(null).toBeNull() })

3. toBeTruthy, toBeFalse

boolean 값을 판별한다.

// 테스트 성공 test('비어있지 않은 문자열은 true 다.', () => { expect('1000peach').toBeTruthy() })

4-3. toBeGreaterThan, toBeGreaterThanOrEqual, toBeLessThan, toBeLessThanOrEqual

  • 숫자의 이상/이하/초과/미만을 판단한다.
    • ex) 길이 제한, 업로드된 파일의 크기 확인
// 테스트 실패 test('ID는 10자 이하여야 한다.', () => { const id = 'HELLO_1000PEACH_WORLD' expect(id.length).toBeLessThanOrEqual(10) })

4-3-1. 주의할 점

자바스크립트는 소수점을 완벽히 연산하지 못하므로 자릿수 처리가 필요하다. toBeCloseTo를 사용하여 값이 근사치인 지 테스트해야 한다.

// 테스트 실패. 결과값: 0.3000000.. test('0.1 더하기 0.2는 0.3이다.', () => { expect(fn.add(0.1, 0.2)).toBe(0.3) }) // 테스트 성공 test('0.1 더하기 0.2는 0.3이다.', () => { expect(fn.add(0.1, 0.2)).toBeCloseTo(0.3) })

4-4. toMatch

해당 문자열을 포함하고 있는 지 판단한다.

// 테스트 성공 test('hello world는 h를 포함한다', () => { expect('hello world').toMatch(/h/i) })

4-5. toContain

배열에서 특정 요소가 있는 지 판단한다.

// 테스트 성공 test('유저 리스트에 Mike가 있다.', () => { const userList = ['Tom', 'Mike', 'Jenny'] const user = 'Mike' expect(userList).toContain(user) })

4-6. toThrow

함수에서 예외가 발생했는 지 확인한다. 특정 에러가 발생했는 지 판별하려면 인수로 에러 내용을 전달한다.

fn.ts

const fn = { add: (number1: number, number2: number) => number1 + number2, makeUser: (name: string, age: number) => ({ name, age, gender: undefined }), throwError: () => { throw new Error('error test') }, } export default fn // 테스트 성공 test('함수 실행 시 에러가 발생한다.', () => { expect(() => fn.throwError()).toThrow() }) // 테스트 실패 test('함수 실행 시 error test 에러가 발생한다.', () => { expect(() => fn.throwError()).toThrow('no error') }) // 테스트 성공 test('함수 실행 시 error test 에러가 발생한다.', () => { expect(() => fn.throwError()).toThrow('error test') })

🔗 참고

이전 게시글

[Effective Typescript] 1장 타입스크립트 알아보기

다음 게시글

[Jest] 비동기 코드 테스트

profile

@1000peach

    GitHubGmailPortfolio
© 2022 1000peach, Powered By Gatsby.