이 글에서는…

자바스크립트의 테스팅 프레임워크 Jest를 설치하고 사용하는 방법을 정리한다.

Jest란?

Jest is a delightful JavaScript Testing Framework with a focus on simplicity.
It works with projects using: Babel, TypeScript, Node, React, Angular, Vue and more!

-- Jest 공식 홈페이지 메인

Jest는 자바스크립트 소스코드를 테스트할 때 사용하는 프레임워크이다.

자바스크립트의 테스팅에는 주로 Jest와 Mocha 둘 중 하나가 사용된다고 하는데, 둘은 다음과 같은 장단점을 가진다.


Jest

장점

  • Test runner, test matcher, test mock까지 모두 지원하는 프레임워크이다.
  • 문서화가 잘 되어 있다.

단점

  • Mocha보다 더 느릴 수 있다.
  • customizing이 Jest에 비해 어렵다.
  • 기능이 적다. Mocha에서는 지원하는 기능을 지원하지 않는 경우가 있다.

Mocha

장점

  • 유연성, 확장성이 좋다.
  • 오랜 기간 동안 사용되어 왔기 때문에, 사용자가 많고 더 나은 지원을 기대할 수 있다.

단점

  • 셋업 과정이 Jest에 비해 더 복잡하다. Assertions, Mocking 등을 하기 위해서 다른 라이브러리를 설치해야 한다.
  • 러닝 커브가 비교적 가파르다.

Jest 설치

아래와 같이 jest를 설치한다.

(npm)

npm install --save-dev jest

(yarn)

yarn add --dev jest

설치가 완료되었으면, package.json에 아래 내용을 추가해주자.

// package.json
{
  // ...
  "scripts": {
    "test": "jest"
  }
  // ...
}

이렇게 하면, npm test 혹은 yarn test라는 명령어 하나만으로 사전에 정의된 테스트들을 한번에 테스트할 수 있다.

// test.js
const sum = require('./sum');

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});

설치 및 환경 세팅이 잘 되었는지 확인하기 위해, 위 파일을 test.js라는 이름으로 프로젝트 디렉토리에 추가한 뒤, npm test 혹은 yarn test을 사용해 테스트를 해보자.

무슨 의미인지 직관적으로 알 수 있을 것인데, Jest에서 제공하는 기능들에 대한 더 자세한 설명은 아래 섹션에서 마저 해볼 것이다.


Jest 기본 사용법

describe('Calculation test', () => {
	test('adds 1 + 2 to equal 3', () => {
	  expect(sum(1, 2)).toBe(3);
	});
  test('adds -2 + 2 to equal 0', () => {
	  expect(sum(-2, 2)).toBe(0);
	});
});

test()

Jest에서 테스트는 test(테스트 이름, 테스트할 함수)의 형태로 사용한다.

Jest에서는 기본값으로 test.js 로 끝나거나, __test__ 디렉토리 안에 있는 파일 이름들 (e.g. reservation.test.js, ./__test__/test_a.js) 안에 있는 모든 test() 함수들에 대해 테스트를 진행한다.

describe()

Jest에서 테스트를 묶는 논리적 단위이다.

하나의 describe 안에 여러 개의 test를 두어 하나의 test suite로 만들 수 있다.

describe(테스트 이름, 테스트할 함수들이 들어 있는 함수)의 형태로 사용한다.

expect()

Jest에서는 일반적으로 expect(검증 대상).matcher(기대값); 와 같은 형태로 테스트를 진행한다.

expect 뒤에 붙는 함수들은 matcher라고 부르며, Jest에서는 여러 종류의 matcher들을 지원한다.


toBe()

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});

앞선 예제에서 나왔던 toBe 함수는 expect()의 인자로 준 값과 toBe()의 인자로 준 값이 같은지 검사한다.

toEqual()

test('checks array equality', () => {
  expect([1, 2, 3]).toEqual([1, 2, 3]);
});

toBe와 toEqual은 얼핏 보면 같은 동작을 하는 함수처럼 보이지만,

toBe는 number, boolean과 같은 원시값들이 같은지 검증하는 반면, toEqual은 객체 안의 값이 같은지를 검증한다.

toBeTruthy(), toBeFalsy()

test("number 0 is falsy but string 0 is truthy", () => {
  expect(0).toBeFalsy();
  expect("0").toBeTruthy();
});

toBeTruthy()와 toBeFalsy()는 자바스크립트의 규칙에 따라, 주어진 값이 false로 평가되는지 true로 평가되는지 판단해 테스트한다.

toHaveLength(), toContain()

test("tests array", () => {
  const alphabets = ["A", "B", "D"];
  expect(alphabets).toHaveLength(3);
  expect(alphabets).toContain("A");
  expect(alphabets).not.toContain("C");
});

toHaveLength는 주어진 배열의 크기를, toContain은 특정 element가 들어있는지 확인한다.

toMatch()

test("tests username", () => {
  const username = 'user1';
  expect(username).toMatch(/^[a-z0-9_]+$/i);
});

toMatch는 주어진 값이 정규표현식에 부합하는지 테스트한다.

toThrow

test("throws error if div by 0", () => {
  // Don't
  expect(divide(3, 0)).toThrow('You cannot divide something by 0.');
});

주어진 상황에서 예외가 발생하는지 확인하는지 테스트한다.

toThrow() 안의 인자에는 에러 객체의 메시지를 넣는다.

그런데 위 주석처리한 대로 테스트 코드를 짠다면, divide(3, 0)을 처리하며 실제로 0으로 나눌 수 없다는 예외가 발생하여 테스트가 항상 실패하게 될 것이다.

따라서, toThrow()를 사용할 때에는 다른 matcher들과는 달리 아래와 같이 함수로 한 번 감싸서 사용한다.

  test("throws error if div by 0", () => {
  // Don't
  expect(() => { divide(3, 0) }).toThrow('You cannot divide something by 0.');
});

그 외에도 테스트 전/후 처리를 하는 방법이 궁금하다면 아래 블로그를 참고하자.

https://www.daleseo.com/jest-before-after/


jest + import export

Jest를 require를 사용한 commonJs가 아닌, import, export와 같은 문법과 같이 사용하고 싶은 사용자들이 있을 것이다.

하지만 위 설정만으로는 import, export와 같은 문법들을 사용할 수 없고, 사용하려고 하면 아래와 같은 오류 메세지들을 마주하게 된다.

Jest encountered an unexpected token
Cannot use import statement outside module
You appear to be using a native ECMAScript module configuration file, which is only supported when running Babel asynchronously.

Jest와 import, export를 함께 사용하는 방법은 크게 2가지로, 아래와 같이 인터넷에 많이 소개되어 있다.


ES6의 문법들이 사용된 javascript(or typescript) 코드를 ES5의 문법이 사용된 js(ts) 파일로 컴파일하여 사용하는 방법

https://poiemaweb.com/jest-esm

https://velog.io/@dacircle/JEST-import-사용하기

--experimental-vm-modules을 사용한 방법

https://study-ihl.tistory.com/191


그러나 Jest 공식 홈페이지에서는 글을 작성하고 있는 현재(2023.07) 기준으로, ESM(ECMAscript Modules)를 사용하는 데에 주의가 필요하다고 하고 있다.

https://jestjs.io/docs/ecmascript-modules

이는 Jest와 ESM을 함께 사용하는 것이 experimental한 기능이기 때문인데, import, export와 같은 문법을 사용하고자 하는 분들은 버그 혹은 완전치 못한 기능들에 유의하여 Jest를 사용하길 바란다.


references

Mocha vs Jest Comparison of Testing Tools in 2022

자바스크립트 테스트 프레임워크 비교 (jest, mocha, jasmine)

Mocha vs Jest (JS Testing Framework)

Jest official website

Jest ECMAScript Modules

Jest matchers

Jest Basic

Jest로 테스트 전/후 처리하기

15.8 Jest에서 import/export를 사용하기

JEST - import 사용하기

Jest에서 ES6 모듈 사용하기 (Expriemental Support)

profile
이예찬

0개의 댓글