본문 바로가기

Web

Unit Test(with Jest)

❔ 유닛 테스트(Unit Test)

  • 소프트웨어의 가장 작은 단위인 "Unit(단위)" 를 격리시켜 테스트하는 방법
  • Unit(단위) : 함수, 메서드, 클래스, 모듈 등
  • 소프트웨어 개발에서 사용되는 기본적인 테스트 방법
  • 개발 초기 단계부터 적용하여 코드의 신뢰성을 높이는 데 중요한 역할

목적 및 특징

  • 각 단위가 의도한 대로 정확히 작동하는지 검증
  • 코드 변경 시 기존 기능이 올바르게 동작하는지 확인
  • 빠르게 실행과 자동화 가능
  • 다른 코드나 외부 의존성과 독립적으로 실행

테스트 유형

1. 상태 테스트

  • 함수의 반환값 검증
  • 객체의 상태 변화 검증

2. 동작 테스트

  • 함수 호출 여부 검증
  • 이벤트 발생 검증

3. 예외 테스트

  • 에러 처리 검증
  • 경계값 테스트

 

유닛 테스트가 필요한 이유

1. 버그 조기 발견

  • 코드 변경 시 즉시 문제 발견이 가능하다.
  • 디버깅 시간을 단축하여 개발 생산성을 향상시킨다.
  • 비용 절감

2. 코드 품질 향상

  • 테스트 작성을 통해 코드의 문제점을 발견하고 더 나은 설계와 구조로 개선이 가능하다.
  • 클린 코드 작성을 유도한다.

3. 리팩토링 안정성

  • 개별 기능의 정확성을 검증하여 전체 시스템의 안정성을 확보할 수 있다.
  • 기존 기능이 올바르게 작동하는지 확인이 가능하다.

4. 문서화 효과

  • 테스트 코드가 해당 기능의 명세가 된다.
  • 새로운 개발자가 코드를 이해하기 쉽다.

 

유닛 테스트 라이브러리

1. Jest (JavaScript/TypeScript)

// Jest를 사용한 테스트 예시
describe('계산기 함수', () => {
  test('덧셈이 정상적으로 동작해야 함', () => {
    expect(add(1, 2)).toBe(3);
  });

  test('0으로 나누면 에러가 발생해야 함', () => {
    expect(() => divide(1, 0)).toThrow('0으로 나눌 수 없습니다');
  });
});
  • 페이스북에서 개발한 가장 널리 사용되는 테스트 프레임워크
  • 내장 assertion 과 mocking 지원
  • 스냅샷 테스트 지원

2. Vitest

  • Vite 기반 테스트 프레임워크
  • Jest 와 유사한 API, 빠른 실행 속도

3. Mocha

  • 유연한 JavaScript 테스트 프레임워크
  • 다양한 assertion 라이브러리와 함께 사용 가능
  • Node.js와 브라우저 환경 모두 지원

 

4. JUnit (Java)

  • Java 생태계에서 가장 널리 사용되는 테스트 프레임워크

6. pytest (Python)

  •  Python용 테스트 프레임워크로 간단하고 확장성 높음

6. NUnit (.NET)

  • .NET 프레임워크를 위한 유닛 테스트 도구

7. RSpec (Ruby)

  • Ruby 언어를 위한 BDD(Behavior Driven Development) 스타일의 테스팅 프레임워크

 

유닛 테스트 작성 원칙 (FIRST)

1. Fast (빠른 실행)

  • 테스트는 빠르게 실행되어야 함
  • 개발자가 자주 실행할 수 있어야 함

2. Independent (독립적)

  • 다른 테스트에 영향을 받지 않아야 함

3. Repeatable (반복 가능)

  • 어떤 환경에서도 같은 결과가 나와야 함
  • 외부 의존성 최소화

4. Self-validating (자가 검증)

  • 테스트는 자동으로 결과를 확인할 수 있어야 함
  • Pass/Fail이 명확해야 함

5. Timely (적시에)

  • 실제 코드 작성 전이나 직후에 작성
  • TDD(Test-Driven Development) 방식 권장

 

Jest 테스트 코드에서 사용되는 주요 개념

1. describe()

describe('Calculator', () => {
  test('addition', () => { /* ... */ });
  test('subtraction', () => { /* ... */ });
});
  • 관련된 테스트들을 그룹화
  • 사용방법 : describe("테스트 그룹 설명", () => { 테스트 코드 })

2. test() / it()

  • 개별 테스트 케이스를 정의하는 함수 (it 은 test 의 별칭)
  • 사용방법 : test("테스트 설명", () => { 테스트 코드 })

3. expect()

  • 값을 테스트하기 위한 함수
  • 모든 테스트에서 결과를 검증할 때 사용
  • 사용방법 : expect(실제값).matcher(기대값)
  • 예시 : expect(sum(1,2).toBe(3))

4. Matchers

  • expect() 와 함께 사용되어 값을 비교
  • 주요  matcher 들
    • toBe() : 엄격한 동등성 비교
    • toEqual() : 깊은 동등성 비교
    • toBeNull() : null 여부 확인
    • toBeTruthy() / toBeFalsy() : 참/거짓 여부 확인
    • toContain() : 배열이나 문자열에 특정 항목 포함 여부 확인

5. beforeEach() / afterEach()

  • 각 테스트 전 / 후에 실행될 코드를 정의
  • 사용방법 : beforeEach(() => { 각 테스트 전에 실행될 코드 })

6. beforeAll() / afterAll()

  • 모든 테스트 전 / 후에 한 번만 실행될 코드를 정의
  • 사용방법 : beforeAll(() => { 모든 테스트 전에 한 번 실행될 코드 })

7. jest.spyOn()

  • 객체의 메서드를 감시
  • 사용방법: jest.spyOn(object, 'methodName');

8. async/await

test('async test', async () => {
  const data = await fetchData();
  expect(data).toBe('peanut butter');
});
  • 비동기 테스트를 작성

9. Coverage

--------------------|---------|----------|---------|---------|
File                | % Stmts | % Branch | % Funcs | % Lines |
--------------------|---------|----------|---------|---------|
All files           |   85.71 |      100 |      80 |   85.71 |
calculator.js       |   85.71 |      100 |      80 |   85.71 |
--------------------|---------|----------|---------|---------|
  • 테스트 코드가 프로덕션 코드를 얼마나 실행했는지 측정
  • 사용방법 : Jest 설정에서 활성화 후 yarn test --coverage 명령어로 실행

10. Mocking

  • 테스트의 격리성을 높이고, 외부 의존성(데이터베이스, API 호출 등)을 제어하여 일관된 테스트 환경 제공

10-1. jest.fn() - MockFunctions

const mockFn = jest.fn();
mockFn.mockReturnValue(42);
expect(mockFn()).toBe(42);
  • 함수의 호출을 추적하고 결과를 제어
  • 모의 함수(mock function)를 생성
  • 사용방법 : const mockFn = jest.fn();

10-2. jest.mock() - Mock Modules

jest.mock('./math');
const math = require('./math');
math.add.mockReturnValue(42);
  • 모듈을 모의 객체로 대체
  • 사용방법 : jest.mock('모듈명');

10-3. (jest.spyOn()) - Spies

const spy = jest.spyOn(console, 'log');
console.log('test');
expect(spy).toHaveBeenCalledWith('test');
  • 기존 객체의 메서드를 감시하거나 대체

10-4. jest.useFakeTimers() - Mock Timers

jest.useFakeTimers();
setTimeout(() => {}, 1000);
jest.runAllTimers();
  • 시간 관련 함수(setTimeout, setInterval 등)를 모의 구현으로 대체

 

Jest 활용 테스트 코드 작성 방법

1. Jest 설치 및 설정

  • jest 설치 후 package.json의 scripts에 test 명령어 추가: "test": "jest"

2. 테스트 파일 생성

  • 테스트할 파일명 뒤에 .test.js  / .test.ts 붙여서 생성

3. 테스트 구조 작성

  • describe() 함수로 테스트 그룹 정의
  • test() 또는 it() 함수로 개별 테스트 케이스 작성

4. 테스트 코드 작성

  • expect() 함수를 사용하여 예상 결과 정의
  • matcher 함수(toBe, toEqual 등)를 사용하여 결과 비교

5. 테스트 실행

  • 터미널 `yarn test` 명령어 실행

* 비동기 코드 테스트

  • 콜백 함수 사용 시 : done 파라미터 사용
  • Promise 반환 시 : return 문 사용 또는 async/await 사용

'Web' 카테고리의 다른 글

프론트엔드 에러 모니터링  (0) 2025.01.18
JWT(JSON Web Token)  (0) 2025.01.18