신입 개발자가 정리한 Jest 테스트 사용 예시와 환경 구성

Description: Jest의 간단한 사용이유, 테스트 예시, 환경구성 등을 정리해보았습니다.

현재 노트: KR-010.60 a
상위 분류: KR-010.60 Jest

#기술스택 #Dev #Jest

글 작성 이유

Jest를 쓰는 이유와 , 사용 방법 ,사용시 고려해볼 점, 그리고 직접 겪어본 여러 환경에 대한 느낀 점 작성해보았습니다.

Jest 사용 이유

통합된 JavaScript를 위한 Test 프레임워크
Jest이전에 여러툴을 사용해서 테스트를 했었어야 했습니다. 그러다보니 통합사용에 있어서 어려움이 많았고, Jest가 등장하게되면서 이런 여러 툴을 따로 설치하고 이를 통합해야하는 번거로움이 사라지면서 인기를 얻게 됐습니다.

추가로 이런 이유로 디팩토로 사용되다보니 커뮤니티도 활발하며 여러 레퍼런스가 존재하기에 JavaScript에서 사용되는 대표적인 Test툴로 사용 돼고있습니다.

이런점은 공식 페이지의 문구에서도 잘 나와있습니다

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는 테스트의 구조를 체계적으로 관리할 수 있도록 블록 구분과 테스트 단위 관리 기능을 제공합니다. 아래는 각각의 개념과 예시입니다.

1. beforeEach와 afterEach를 통한 테스트

let data;

beforeEach(() => {
  // 테스트 시작 전 배열 초기화
  data = [1, 2, 3];
});

afterEach(() => {
  // 테스트 후 배열 클리어
  data = [];
});

test('배열에 새 값을 추가', () => {
  data.push(4);
  expect(data).toEqual([1, 2, 3, 4]);
});

test('배열의 길이 확인', () => {
  expect(data.length).toBe(3);
});

2. beforeAll와 afterAll을 통한 테스트

let dbConnection;

beforeAll(() => {
  // 모든 테스트 전에 데이터베이스 연결
  dbConnection = { isConnected: true };
});

afterAll(() => {
  // 모든 테스트 후 데이터베이스 닫기
  dbConnection = null;
});

test('데이터베이스 연결 상태 확인', () => {
  expect(dbConnection.isConnected).toBe(true);
});

test('데이터베이스에 데이터 추가', () => {
  const data = { id: 1, value: 'test' };
  expect(data).toEqual({ id: 1, value: 'test' });
});

3. test.each를 통한 반복 테스트

test.each([
  [1, 2, 3],
  [-1, -1, -2],
  [0, 0, 0],
])('add(%i, %i) should return %i', (a, b, expected) => {
  function add(x, y) {
    return x + y;
  }
  expect(add(a, b)).toBe(expected);
});

Jest 사용시 고려해볼점

Jest를 사용할 때 어떤 테스트를 만들것인가? return값은? 그리고 다양한 테스트케이스를 커버할 수 있는가? 등이 사용할 떄 고려해봐야할 점등입니다.
해당 케이스나 방법은 많이 사용할 수록 늘게되는데, 현재 배운 정도로는 다음의 다양한 테스트 케이스가 있습니다.

성공 케이스 실패 케이스 구분

명확한 메시지와 반환값을 통해 특정 메소드의 성공시의 기대값과 실패값을 명시합니다.

test('더하기 함수 성공케이스: 두 값을 입력 받아 합을 반환', () => {
  expect(add(2, 3)).toBe(5);

test('더하기 함수 실패케이스: 입력 값에 숫자가아닌 문자가 들어간 경우 에러 반환', () => {
  expect(() => add('a', 3)).toThrow('Invalid input');
});

Mocking 함수를 통한 의존성 분리

입출력이 복잡한 경우 mocking 기능을 통해 jest.fnmockImplementation등을 통해 임의의 형태로 만든 값을 통해 테스트합니다

const fetchData = jest.fn().mockResolvedValue('data');

test('Mocking을 통해 fetchData 함수의 반환값 테스트', async () => {
  const result = await fetchData();
  expect(result).toBe('data');
});

랜덤값을 생성하는 경우 값을 명시

랜덤 값이나 동적 데이터를 테스트할 때는 값을 고정시켜 일관성을 유지합니다.

const generateRandomNumber = jest.fn().mockReturnValue(42);

test('랜덤 값을 고정하여 반환값 테스트', () => {
  const randomNumber = generateRandomNumber();
  expect(randomNumber).toBe(42);
});

날짜에 관한 테스트 중 날짜를 고정

날짜와 시간에 의존하는 테스트는 Jest의 FakeTimers를 사용해 날짜를 고정하여 정확성을 보장합니다.

jest.useFakeTimers().setSystemTime(new Date('2024-01-01'));

test('고정된 날짜를 사용하여 테스트', () => {
  const currentYear = new Date().getFullYear();
  expect(currentYear).toBe(2024);
});

Jest 테스트 환경 사례

Jest를 사용할 때의 기술적인 내용입니다. 테스트 파일 작성에는 몇 가지 규칙과 관행이 있습니다. 그리고 Jest를 사용하는 다양한 환경을 직접 겪어보면서 느낀 장단점들입니다.

Jest 테스트 파일 규칙

개인적으로는 tests 디렉토리에 ClassNameTest.js 방식을 선호합니다. 일단 테스트 파일을 중앙 저장소에서 관리할 수 있고, 어떤 클래스에대한 테스트인지 파일이름에 명시해서 보는 사람이 파악하기 쉽기 때문입니다.

모든 파일 테스트 하는 경우

Jest는 기본적으로 프로젝트 내의 모든 테스트 파일을 실행합니다.
npx jest

단일 파일 테스트 경우

특정 파일만 지정하여 테스트가 가능합니다
npx jest path/to/yourFile.test.js

단일 테스트 케이스 테스트 한 파일에서도 특정 메소드만 테스트하고싶은 경우

저장시마다 테스트하고 싶은 경우

https://marketplace.visualstudio.com/items?itemName=Orta.vscode-jest