Notepad

Vitest 메모: 빠르고 쉽게 유닛 테스트 시작하기

왜 Vitest인가?

Vite 기반 프로젝트에서 테스트 환경이 너무 무겁거나 느릴 때가 많았다. Vitest는 Vite의 장점을 그대로 가져와서 빠르고 간결하게 테스트를 할 수 있게 해준다.

  • 속도: Vite를 썼으니 당연히 빠르다. HMR 원리로 변경된 파일만 재실행해줘서 개발 속도가 확 올라간다.
  • API: Jest API를 거의 다 지원해서 기존에 쓰던 방식 그대로 쓰면 된다. 마이그레이션이 쉽다.
  • 설정: Vite 설정(Alias, 플러그인 등)을 그대로 공유하니까 설정할 게 거의 없다.
  • 모던: TypeScript, ESM(ES Module) 기본 지원. 요즘 프로젝트에 딱 맞다.

Vitest 시작하기: 설치와 기본 코드 구조

설치

개발 의존성으로 설치하면 끝.

npm install -D vitest
# yarn add -D vitest

기본 코드 템플릿

테스트 파일은 보통 .test.ts 또는 **.spec.ts**로 만든다.

// sum.test.js

// 필수 import 항목: test/it, expect, describe
import { describe, expect, test } from 'vitest';
import { sum } from './sum.js'; // 테스트할 대상

// 💡 describe: 테스트 그룹핑 (가독성 좋게!)
describe('sum 함수 테스트', () => {

  // 💡 test (it): 실제 테스트 케이스
  test('1 + 2 는 3이 나와야 정상', () => {
    // expect().toBe(): 기본 원시 값 비교 (===)
    expect(sum(1, 2)).toBe(3);
  });

  test('음수 처리도 확인', () => {
    expect(sum(-5, 3)).toBe(-2);
  });
});

자주 쓰는 Matcher (검증 함수)

Matcher 역할 사용 상황
.toBe(value) 값과 타입이 동일한지 (===) 확인 숫자, 문자열, 불리언 등 원시 값 비교
.toEqual(value) 객체나 배열의 내용이 동일한지 확인 객체, 배열 등 참조 타입 비교 시 필수
.not.toBe(value) 아닐 때 성공 (.not을 붙여 반전) 값이 다름을 명시적으로 테스트
.toBeTruthy() 값이 참처럼 평가되는지 조건문 통과 여부 확인 (1, 'a', {} 등)
.toBeFalsy() 값이 거짓처럼 평가되는지 조건문 실패 여부 확인 (0, '', null, undefined 등)
.toContain(item) 배열이나 문자열 포함 여부 확인 배열에 특정 요소가 있는지 검사
.toThrow(error?) 특정 함수 호출 시 에러가 발생하는지 확인 예외 처리 로직 테스트

테스트 환경 설정: 후크와 독립성

테스트는 항상 독립적이어야 한다. **후크(Hooks)**를 써서 환경을 격리하자.

후크 실행 시점 용도
beforeEach(fn) 테스트 실행 테스트 데이터/상태 초기화 (가장 중요)
afterEach(fn) 테스트 실행 정리 (Mock 초기화, 리소스 해제)
beforeAll(fn) 전체 그룹 시작 에 1회 DB 연결, 서버 시작 등 무거운 작업
afterAll(fn) 전체 그룹 완료 에 1회 DB 연결 해제, 서버 종료 등
// beforeEach 사용 예시: user 객체를 항상 깨끗하게 초기화
let user;

describe('사용자 상태 테스트', () => {
  beforeEach(() => {
    // 매 테스트마다 user는 { id: 1 }로 초기화됨
    user = { id: 1, loggedIn: false };
  });

  test('로그인 전 상태 확인', () => {
    expect(user.loggedIn).toBeFalsy();
  });

  test('로그인 후 상태 변경', () => {
    user.loggedIn = true;
    expect(user.loggedIn).toBeTruthy();
    // 💡 다음 테스트에는 영향을 주지 않는다! (beforeEach 덕분)
  });
});

스크립트 활용 팁: 상황별 Vitest 명령어

package.json"test:unit": "vitest"만 넣어두는 건 아쉽다. 상황에 따라 다양한 옵션을 활용해야 한다.

내 스크립트 명령어 내가 쓸 용도
"test:unit": "vitest" vitest 개발 중에 띄워놓고 쓰는 실시간 감시 모드 (Watch)
"test:ci": "vitest run" vitest run 배포 전 CI에서 딱 한 번만 돌리고 결과를 확인해야 할 때
"test:cov": "vitest run --coverage" vitest run --coverage 코드 커버리지 확인. 테스트가 코드를 얼마나 커버하는지 리포트로 뽑아볼 때.
"test:ui": "vitest --ui" vitest --ui 브라우저에서 시각적으로 테스트 결과, 로그, 커버리지를 볼 때 (디버깅 편의성)
"test:focus": "vitest src/auth/**/*.test.ts" vitest [파일 경로/패턴] 특정 기능만 집중적으로 작업하고 테스트해야 할 때

🚨 꼭 기억할 것!

  • 개발 중: test:unit (Watch 모드)
  • 자동화 환경/최종 확인: test:ci (Run 모드)
  • 코드 품질 관리: test:cov (커버리지)
profile

Notepad

@Apio

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!