[javascript] Jest

·2024년 3월 6일
0

Javascript

목록 보기
15/16
post-thumbnail

TDD

개발 방법론 중 하나인 TDD(Test-Driven Development)는 테스트 주도의 개발을 의미한다. 로직을 작성하기 전에 테스트 케이스를 정의하여 테스트를 통과하지 못하는 상태를 만들고(Red), 로직을 완성시켜 가면서(Blue) 최종적으로 테스트를 통과하도록(Green) 하는 방식으로 진행된다.
번거롭다고 느낄 수 있는 방식을 사용하여 개발을 하는 이유는 다음과 같다.

  • 방금 작성한 코드가 잘 작동하는 코드인지를 판별할 수 있다.
  • 코드를 어떻게 작성해야 할지 무엇을 해야 할지 결정하는데 도움을 준다.
  • 리팩토링을 하거나 새로운 기능을 구현할 때 기존 테스트 코드를 기반으로 사이드 이펙트를 방지할 수 있다.
  • 버그 발생 시 실패한 테스트로부터 원인을 찾는 데 도움을 줄 수 있다. 즉, 디버깅 시간을 줄여준다.
  • 테스트 문서 및 스펙 문서의 역할을 할 수 있다.

물론 이러한 장점만 있는 것은 아니다. 개발자가 테스트 코드 작성에 익숙해지는 데까지의 비용이 들 수 있다. 즉, 생산성 측면에서 초기에는 어려움이 있을 수 밖에 없는 구조이다.
그럼에도 React나 Vue, ESLint 등 Javascript 기반 오픈소스 프로젝트를 보면 테스트 코드가 포함되어 있는 경우가 많다. 테스트 코드 작성은 규모가 큰 오픈소스 프로젝트의 경우 보편적이며 거의 필수적으로 진행되고 있다.

Jest

Jest 란?

Jest는 Test Runner, Test Matcher, Test Mock까지 제공해주는 All in one 테스팅 프레임워크이다. 이러한 테스팅 도구를 사용하게 되면 작성된 코드가 제대로 동작되는지를 확인할 수 있다.

  • Test Runner : 테스트 케이스를 실행하고 결과를 보고하는 소프트웨어로, 테스트 스크립트를 자동으로 실행하고 테스트가 성공적으로 통과했는지 또는 실패했는지를 판단하여 결과를 제공한다.
  • Test Matcher : 테스트의 검증 부분에서 사용되며, 예상 결과와 실제 결과를 비교하는 데 사용되는 표현식이다.
  • Test Mock : 테스트 중인 코드 외부의 의존성을 모방한 객체이다. DB, 네트워크 호출 등 실제 객체의 동작을 흉내내거나 예측 가능한 방식으로 대체하여 테스트의 실행 속도를 개선한다.

Jest를 사용해 간단한 Unit Test를 작성할 수 있다.

Jest를 이용한 테스트 코드 작성

설치 및 기본 사용법

npm install --save-dev jest

npm 또는 yarn으로 jest 설치 후 package.json을 세팅한다.

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

Jest로 작성되는 테스트 코드의 구조는 다음과 같다.

test('테스트 설명', () => {
  expect('검증 대상').toXXX('기대 결과');
})

테스트 고드를 작성하는 경우 테스트 코드가 제대로 동작하는지 검증하기 위해 처음에는 실패하는 테스트를 작성한 뒤 테스트를 통과하게 수정하는 과정을 거치게 된다.

Matcher

expect 뒤에 붙는 .toXXX 부분이 Test Matcher이다.

  • .toBe(): 검증 대상과 기대 결과가 동일한지를 검증한다. 객체를 검증해야 하는 경우에는 사용하지 못한다.
    test('two plus two is four', () => {
      expect(2+2).toBe(4);
    });
  • .toEqual(): 위와 마찬가지로 검증 대상과 기대 결과가 동일한지 검증한다. 객체, 배열도 재귀적으로 확인하므로 검증 가능하다
	test('obejct assignment', () => {
      const data = { one: 1 };
      data['two'] = 2;
      expect(data).toEqual({ one: 1, two: 2});
    });
  • .toBeTruthy(), .toBeFalsy(): 검증 대상이 true인지 false인지 검증한다.
	test('null', () => {
      const n = null;
      expect(n).toBeNull();
      expect(n).toBeDefined();
      expect(n).not.toBeUndefined();
      expect(n).not.toBeTruthy();
      expect(n).toBeFalsy();
    });

    test('undefined', () => {
      const u = undefined;
      expect(u).not.toBeNull();
      expect(u).not.toBeDefined();
      expect(u).toBeUndefined();
      expect(u).not.toBeTruthy();
      expect(u).toBeFalsy();
    });

    test('zero', () => {
      const z = 0;
      expect(z).not.toBeNull();
      expect(z).toBeDefined();
      expect(z).not.toBeUndefined();
      expect(z).not.toBeTruthy();
      expect(z).toBeFalsy();
    });
  • .toHaveLength(): 검증 대상의 배열의 길이를 검증한다.
	const shoppingList = [
      "diapers",
      "kleenex",
      "trash bags",
      "paper towels",
      "beer"
    ];

	test('the number of shopping list', () => {
      expect(shoppingList).toHaveLength(5);
    });
  • .toContain(): 검증 대상의 배열에 특정 원소가 있는지를 검증한다.
	const shoppingList = [
      "diapers",
      "kleenex",
      "trash bags",
      "paper towels",
      "beer"
    ];

	test('the shopping list has beer on it', () => {
      expect(shoppingList).toContain('beer');
      expect(new Set(shoppingList)).toContain('beer');
    });
  • .toMatch(): 검증 대상에 대해 정규식 기반으로 검증이 필요한 경우 사용한다.
	test('there is no I in team', () => {
      expect('team').not.toMatch(/I/);
    });

	test('but there is a "stop" in Christoph', () => {
      expect('Christoph').toMatch(/stop/);
    });
  • .toThrow(): exception 발생 여부를 검증한다. 문자열 혹은 정규식을 인자로 넘기면 에러 메시지와 동일한지 검증한다.
	function comileAndroidCode() {
      throw new Error('you are using the wrong JDK');
    }

	test('compiling android goes as expected', () => {
      expect(compileAndroidCode).toThrow();
      expect(compileAndroidCode).toThrow(Error);
      
      expect(compileAndroidCode).toThrow('you are using the wrong JDK');
      expect(compileAndroidCode).toThrow(/JDK/);

< 출처 : https://github.com/im-d-team/Dev-Docs/blob/master/Javascript/Jest.md >

profile
개발을 개발새발 열심히➰🐶

0개의 댓글