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(커버리지)
'dev > 기타' 카테고리의 다른 글
| [정리] 제대로 배우는 자바스크립트(1) (0) | 2023.11.18 |
|---|---|
| [정리] 핵심만 배우는 git (0) | 2023.08.27 |
| port 오픈 확인 (0) | 2023.07.21 |
| 카프카 스트림즈와 ksqlDB 정복 - 7장 Processor API (0) | 2023.07.04 |
| [정리] 실전 카프카 개발부터 운영까지(5) (0) | 2022.10.20 |