Jest

2021-01-21 hit count image

create-react-app에서 테스트에 많이 사용되는 Jest에 대해서 알아봅시다.

create-react-app 시리즈

이 블로그 포스트는 시리즈로 제작되었습니다. 다음은 create-react-app의 시리즈 리스트입니다.

개요

테스트는 서비스를 개발하고 유지하기 위한 필수 조건중 하나입니다. 테스트는 모든 기능을 확인하는 시간을 줄여 주고, 버그 발생을 예방하거나 같은 버그가 다시 발생하지 않도록 해줍니다. 또한 코드를 수정하였을 때, 수정한 코드의 사이드 이펙트를 찾아주거나 예상치 못한 동작을 발견해 주기도 합니다.

이처럼 테스트 코드는 소프트웨어 개발에서 중요한 역할을 하고 있습니다. 그리고 대부분의 언어에서는 해당 언어에 맞는 테스트 프레임워크들이 존재하고 있습니다. JavaScript에서도 Mocha, Jasmine, Karma 등 많은 테스트 프레임워크가 존재하며, Jest도 자바스크립트 테스트 프레임워크중 하나입니다.

create-react-app에서는 기본적으로 Jest를 사용하고 있습니다. 이번 블로그 포스트에서는 Jest의 특징과 사용법에 대해서 알아봅시다.

Jest의 특징

Jest는 리액트와 마찬가지로 페이스북에서 개발하고 관리하는 자바스크립트 테스트 프레임워크입니다. 자바스크립트 테스트 프레임워크이므로 리액트 이외에도 타입스크립트, 노드, Angular, Vue 등도 테스트가 가능합니다.

Jest는 단순함에 집중하여 누구나 쉽게 테스트를 할 수 있도록 하고 있습니다. Jest는 단순함 이외에 다음과 같은 특징을 가지고 있습니다.

제로 설정

테스트를 시작하기 위해 많은 테스트 프레임워크들이 많은 설정을 해야 하지만, Jest는 이런 설정때문에 쉽게 테스트를 하지 못하는 문제를 해결하기 위해 제로 설정을 지원하고 있습니다.

스냅샷

자바스크립트에서 값을 일일이 확인하기 어려울 정도로 큰 오브젝트가 존재할 수 있습니다. 이런 경우를 대비하여 Jest는 스냅샷 기능을 제공하며, 스냅샷을 통해 큰 오브젝트를 저장한 후, 추후 코드 변경에 의해 오브젝트가 변경되면 에러를 표시하도록 하고 있습니다. 리액트에서는 이 스냅샷 기능을 통해 화면에 렌더링된 리액트 컴포넌트의 변경 사항을 체크합니다.

테스트 코드의 분리

Jest에서 테스트 코드는 완전 분리되어 있고, 서로 영향을 주지 않습니다. 이렇게 완전 분리된 테스트는 동시 실행을 가능하게 하며, 동시 진행되는 테스트는 전체 테스트 시간을 단축시켜 줍니다.

간단한 API

Jest는 단순함을 지향하기 때문에, 제공하는 API도 매우 단순합니다. 또한 –coverage 옵션을 사용하여 간단하게 테스트 코드 커버리지를 확인할 수 있습니다.

사용법

이제 실제 Jest를 사용하는 방법에 대해서 알아봅시다. 여기서 소개하는 소스 코드는 아래에 깃헙 링크에서 확인할 수 있습니다.

일단 Jest를 사용하기 위해서는 자바스크립트 프로젝트가 필요합니다. Jest를 연습하기 위한 폴더를 생성한 후, 다음 명령어를 실행하여 자바스크립트 프로젝트를 준비합니다.

# mkdir jest-example
# cd jest-example
npm init

위에 명령어를 실행하면, 여러 질문들이 나오는데, 모두 Enter 키를 눌러 진행합니다.

모든 질문에 Enter 키를 눌러 진행하였다면, 해당 폴더에 package.json 파일이 생성된 것을 확인할 수 있습니다. 이제 해당 폴더에 index.js 파일과 index.test.js 파일을 생성하여 Jest를 사용할 준비를 합니다.

여기서 index.js 파일을 실제 우리가 개발에 사용할 내용들이 추가될 것이며, index.test.js 파일에는 index.js 파일에 관한 테스트 내용이 추가될 예정입니다.

Jest 설치

다음 명령어를 실행하여 Jest를 설치합니다.

npm install --save-dev jest

설치가 완료되었다면 package.json 파일을 열고 scripts 항목을 다음과 같이 수정합니다.

"scripts": {
  "test": "jest --watch"
},

이제 다음 명령어를 실행하여 Jest를 실행해 본다.

npm run test

아직 아무 테스트 코드가 없으므로 에러가 나올 것이다. 이제 테스트 코드를 추가해 보면서 Jest의 사용법을 확인해 보자.

toBe

이제 index.js 파일을 열고 다음과 같이 수정한다.

const sum = (a, b) => {
  return a + b;
};

module.exports = {
  sum,
};

매개변수 두 개를 전달 받아 더하는 단순한 자바스크립트 코드이다. 이제 이 코드를 테스트하기 위해 index.test.js 파일을 열고 다음과 같이 수정한다.

const { sum } = require('./index');

describe('test index.js file', () => {
  it('sums a and b', () => {
    let result = sum(1, 2);
    expect(result).toBe(3);
    result = sum(3, 4);
    expect(result).toBe(7);
  });
});

우선 index.js 파일에서 sum 함수를 가져온다.

const { sum } = require('./index');

그리고 Jest의 describe 함수를 사용하여 설명문과 함께 테스트 코드들을 포함하고 있는 콜백 함수를 지정한다.

describe('test index.js file', () => {
  ...
});

테스트 코드 작성을 위해 Jest의 it 함수를 사용하며, describe와 마찬가지로 설명문과 함께 테스트 코드가 작성된 콜백 함수를 지정한다.

it('sums a and b', () => {
  ...
});

이제 실제 테스트를 위해 Jest의 expect안에 확인하고자 하는 값을 넣고, toBe를 사용하여 해당 값의 기대값을 추가하여 테스트가 우리가 기대한 대로 움직이는지 확인한다.

let result = sum(1, 2);
expect(result).toBe(3);

좀 더 단순하게 아래와 같이 사용할 수 있다.

expect(sum(1, 2)).toBe(3);

Jest에서 위와 같이 우리가 확인하고자 하는 값과 기대값을 추가함으로써 테스트 코드를 작성할 수 있다.

이렇게 파일을 수정하고 저장하면 앞에서 실행한 jest --watch에 의해 Jest가 변경된 파일을 인식하고 자동으로 테스트를 실행하여 다음과 같은 결과를 표시하는 것을 알 수 있다.

 PASS  ./index.test.js
  test index.js file
    ✓ sums a and b (1 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.712 s, estimated 1 s

toEqual

자바스크립트를 조금 공부하였다면 자바스크립트의 Object 비교는 쉽지 않다는 것을 알 수 있다.

const temp = {
  name: 'Yakuza',
  age: 20
}

console.log(temp == {
  name: 'Yakuza',
  age: 20
});
// false

Jest에서는 Object를 비교하기 위한 toEqual 함수를 제공하고 있다. 우선 index.js 파일을 열고 다음과 같이 수정한다.


const makeUser = (name, age) => {
  return {
    name,
    age,
  };
};

module.exports = {
  
  makeUser,
};

그리고 index.test.js 파일을 열고 다음과 같이 수정한다.

const { ..., makeUser } = require('./index');

describe('test index.js file', () => {
  ...
  it('makes a person', () => {
    expect(makeUser('Yakuza', 20)).toEqual({
      name: 'Yakuza',
      age: 20,
    });
  });
});

Jest에서는 앞에서 사용한 toBe 처럼 toEqual 함수를 사용하면 Object를 테스트할 수 있다.

이렇게 파일을 수정하고 저장하면, 다음과 같은 결과값을 확인할 수 있다.

 PASS  ./index.test.js
  test index.js file
    ✓ sums a and b
    ✓ makes a person (1 ms)

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        0.577 s, estimated 1 s

toContain

Jest에서는 배열안에 특정값이 포함되어 있는지 여부를 확인할 수 있는 toContain 함수를 제공하고 있다.

우선 index.js 파일을 열고 다음과 같이 수정한다.

...

const makeRange = (start, end) => {
  let result = [];
  for (let i = start; i <= end; i++) {
    result.push(i);
  }
  return result;
};

module.exports = {
  ...
  makeRange,
};

새로 추가한 함수는 배열의 시작값과 끝값을 전달받아 배열을 만드는 함수이다. 그럼 이 함수를 테스트하기 위해 index.test.js 파일을 열고 다음과 같이 수정한다.

const { ..., makeRange } = require('./index');

describe('test index.js file', () => {
  ...
  it('has 3', () => {
    expect(makeRange(1, 4)).toContain(2);
  });
});

위와 같이 배열의 특정값이 포함되어 있는지 확인하기 위해서, Jest에서 toContain을 사용한다.

이렇게 파일을 수정하고 저장하면, 다음과 같은 결과값을 확인할 수 있다.

 PASS  ./index.test.js
  test index.js file
    ✓ sums a and b (1 ms)
    ✓ makes a person
    ✓ has 3

Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        0.604 s, estimated 1 s

기타

Jest에는 여기서 소개한 함수들 이외에 많은 함수들을 제공하고 있다. 아래에 링크를 통해 Jest에서 제공하는 함수들을 확인할 수 있다.

코드 커버리지

그럼 마지막으로 Jest의 코드 커버리지를 실행해 봅시다. 현재 실행중인 명령어를 취소하고 다음 명령어를 실행해 봅니다.

npx jest --coverage

이렇게 Jest를 커버리지 옵션(–coverage)으로 실행하면 다음과 같이 코드 커버리지 결과를 얻을 수 있다.

 PASS  ./index.test.js
  test index.js file
    ✓ sums a and b (2 ms)
    ✓ makes a person
    ✓ has 3 (1 ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |
 index.js |     100 |      100 |     100 |     100 |
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        2.703 s

완료

이번 블로그 포스트에서는 create-react-app에서 기본적으로 사용되는 Jest에 관해서 알아보았습니다. 앞으로 create-react-app에서 Jest로 테스트해 봅시다.

제 블로그가 도움이 되셨나요? 하단의 댓글을 달아주시면 저에게 큰 힘이 됩니다!

책 홍보

스무디 한 잔 마시며 끝내는 React Native 책을 출판한지 벌써 2년이 다되었네요.
이번에도 좋은 기회가 있어서 스무디 한 잔 마시며 끝내는 리액트 + TDD 책을 출판하게 되었습니다.

아래 링크를 통해 제가 쓴 책을 구매하실 수 있습니다.
많은 분들에게 도움이 되면 좋겠네요.

스무디 한 잔 마시며 끝내는 React Native, 비제이퍼블릭
스무디 한 잔 마시며 끝내는 리액트 + TDD, 비제이퍼블릭
Posts