Vite 프로젝트에서 테스트를 시작한다면 Vitest는 가장 자연스럽게 검토할 수 있는 선택지입니다. 이 글은 설치, 실행 스크립트, 설정 파일, jsdom 환경, 테스트를 늘려 가는 순서를 실무 흐름에 맞춰 정리합니다.- Vite 프로젝트에서 Vitest를 쓰는 이유
- Vitest 설치와 기본 실행
- Vite 설정과 Vitest 설정 연결하기
- jsdom과 테스트 환경 선택
- 실무에서 테스트를 늘리는 순서
- 정리: Vite 프로젝트의 테스트 출발점으로서
Vite 프로젝트에서 Vitest를 쓰는 이유

Vite로 만든 프론트엔드 프로젝트는 개발 서버, 모듈 해석, 빠른 변환 속도에 익숙해져 있습니다. 여기에 테스트 도구를 붙일 때도 같은 개발 경험을 유지하고 싶다면 Vitest가 좋은 출발점이 됩니다. Vitest는 Vite의 설정과 생태계를 적극적으로 활용하기 때문에, 이미 Vite를 쓰는 프로젝트에서는 테스트 환경을 비교적 자연스럽게 연결할 수 있습니다.
Jest를 써본 개발자라면 describe, it, expect, beforeEach 같은 테스트 작성 방식이 낯설지 않을 것입니다. Vitest도 이런 API를 비슷하게 제공하므로 테스트 문법 자체보다 프로젝트 설정과 실행 흐름에 집중할 수 있습니다. 특히 ESM, TypeScript, 최신 프론트엔드 도구 체인과 맞물릴 때 설정 부담이 줄어드는 편입니다.
Vite 생태계와 맞는 테스트 러너
Vitest의 장점은 단순히 빠르다는 말로 끝나지 않습니다. 이미 프로젝트가 vite.config.ts 또는 vite.config.js에 별칭, 플러그인, 환경 설정을 갖고 있다면 테스트에서도 그 설정을 함께 고려할 수 있습니다. 예를 들어 @ 같은 경로 별칭을 애플리케이션 코드에서 쓰고 있다면, 테스트 코드에서도 같은 방식으로 가져오기를 유지하는 것이 관리하기 쉽습니다.
Jest 대신 Vitest를 고려하는 상황
Jest가 나쁜 선택이라는 뜻은 아닙니다. 이미 큰 프로젝트에서 Jest 설정과 테스트 자산이 안정적으로 운영되고 있다면 그대로 유지하는 편이 나을 수 있습니다. 다만 새 Vite 프로젝트이거나, 기존 Vite 프로젝트에 처음 테스트를 붙이는 상황이라면 도구 체인을 억지로 늘리지 않고 시작할 수 있다는 점에서 Vitest가 실용적입니다.
Vitest 설치와 기본 실행
기존 Vite 프로젝트에 Vitest를 추가하는 흐름은 간단합니다. 먼저 개발 의존성으로 vitest를 설치하고, package.json에 테스트 실행 스크립트를 추가한 뒤, 작은 유틸 함수부터 테스트 파일을 만들어 실행해 보면 됩니다.
필요한 패키지 설치
npm을 사용한다면 다음 명령으로 vitest를 설치할 수 있습니다. pnpm이나 yarn을 쓰는 프로젝트라면 같은 의미의 설치 명령으로 바꾸면 됩니다.
npm install -D vitest
React 컴포넌트 테스트까지 염두에 둔다면 나중에 @testing-library/react, @testing-library/jest-dom, jsdom 같은 패키지가 추가로 필요할 수 있습니다. 하지만 처음부터 모두 설치할 필요는 없습니다. 테스트하려는 코드가 단순 함수인지, 브라우저 DOM을 다루는지에 따라 필요한 도구를 나누는 편이 좋습니다.
package.json 스크립트 구성
package.json에는 보통 test 스크립트와 test:run 스크립트를 나눠 둡니다. 개발 중에는 감시 모드가 편하고, CI에서는 한 번 실행하고 종료되는 명령이 필요하기 때문입니다.
{
"scripts": {
"test": "vitest",
"test:run": "vitest run"
}
}
npm run test는 파일 변경을 감시하면서 테스트를 반복 실행하는 개발용 흐름에 잘 맞습니다. 반면 npm run test:run은 GitHub Actions 같은 자동화 환경에서 실패 여부만 확인할 때 적합합니다.
첫 테스트 파일 작성
처음 테스트할 코드는 복잡한 화면보다 작은 함수가 좋습니다. 예를 들어 금액을 표시하는 formatPrice 함수가 있다면, 기대하는 문자열이 정확히 나오는지만 확인해도 테스트 환경이 제대로 동작하는지 알 수 있습니다.
export function formatPrice(value: number) {
return `${value.toLocaleString("ko-KR")}원`;
}
import { describe, expect, it } from "vitest";
import { formatPrice } from "./formatPrice";
describe("formatPrice", () => {
it("숫자를 원화 문자열로 변환한다", () => {
expect(formatPrice(12000)).toBe("12,000원");
});
});
테스트 파일 이름은 보통 formatPrice.test.ts처럼 대상 파일 이름에 .test를 붙입니다. 프로젝트에 따라 __tests__ 폴더를 따로 둘 수도 있지만, 작은 프로젝트에서는 대상 코드 옆에 테스트 파일을 두는 방식이 읽기 쉽습니다.
Vite 설정과 Vitest 설정 연결하기
Vitest 설정은 별도 파일로 분리할 수도 있고, vite.config.ts 안에 함께 둘 수도 있습니다. Vite 프로젝트에서 테스트를 시작하는 단계라면 기존 설정 파일에 test 옵션을 추가하는 방식이 이해하기 쉽습니다.
발행 직전에는 사용 중인 Vite와 Vitest 버전의 공식 문서를 기준으로 test 옵션 이름, 기본값, 환경 설정 방식이 바뀌지 않았는지 한 번 확인하는 것이 좋습니다.
vite.config에서 test 옵션 다루기
vite.config.ts에서 defineConfig를 사용하고 있다면 test 옵션에 테스트 환경, 전역 API 사용 여부, 설정 파일 등을 지정할 수 있습니다. 단, test 옵션의 타입을 자연스럽게 인식하려면 vitest/config에서 defineConfig를 가져오는 방식을 고려할 수 있습니다.
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
environment: "node",
globals: false
}
});
globals를 false로 두면 테스트 파일마다 describe, it, expect를 명시적으로 가져와야 합니다. 처음에는 조금 번거로워 보이지만, 어떤 API를 쓰는지 파일 안에서 바로 드러나기 때문에 유지보수에는 도움이 됩니다.
TypeScript 프로젝트에서 확인할 부분
TypeScript 프로젝트에서 globals를 true로 설정한다면 tsconfig.json의 types에 vitest/globals를 추가해야 할 수 있습니다. 반대로 명시적 import를 쓰는 방식이라면 이 설정 없이도 충분한 경우가 많습니다.
{
"compilerOptions": {
"types": ["vitest/globals"]
}
}
운영 중인 프로젝트라면 tsconfig.app.json, tsconfig.node.json, tsconfig.json이 나뉘어 있을 수 있습니다. 이때는 테스트 파일이 어느 설정의 영향을 받는지 확인해야 합니다. 설정을 한 곳에 급하게 몰아넣기보다, 현재 프로젝트의 TypeScript 구성 방식에 맞춰 최소한으로 추가하는 편이 안전합니다.
jsdom과 테스트 환경 선택

Vitest를 설정하다 보면 environment 값을 무엇으로 둘지 고민하게 됩니다. 기본적으로 단순 함수, 데이터 변환, 날짜 계산, 문자열 처리처럼 브라우저 화면과 무관한 코드는 node 환경이면 충분합니다. 이 경우 실행이 가볍고 테스트 의도도 명확합니다.
node 환경으로 충분한 경우
formatPrice, parseQuery, calculateTotal 같은 함수는 브라우저 window나 document가 필요하지 않습니다. 이런 테스트에 jsdom을 붙이면 동작은 할 수 있지만, 필요 없는 환경을 켜는 셈입니다. 처음 테스트를 늘릴 때는 가능한 한 단순한 환경에서 검증할 수 있는 코드부터 시작하는 것이 좋습니다.
DOM이나 컴포넌트 테스트에 jsdom이 필요한 경우
document.createElement, localStorage, HTMLElement, React 컴포넌트 렌더링처럼 브라우저와 비슷한 환경이 필요하다면 jsdom을 설치하고 environment를 jsdom으로 바꿉니다.
npm install -D jsdom
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
environment: "jsdom"
}
});
모든 테스트에 jsdom이 필요한 것은 아닙니다. 프로젝트 전체 설정을 jsdom으로 두는 방식도 가능하지만, 테스트가 많아질수록 환경을 구분하고 싶어질 수 있습니다. 그때는 파일별 환경 주석이나 별도 설정 분리를 검토할 수 있습니다. 처음 도입 단계에서는 팀이 이해하기 쉬운 하나의 기준을 정하고, 예외가 생길 때 조정하는 편이 현실적입니다.
실무에서 테스트를 늘리는 순서
운영 중인 프로젝트에 테스트를 붙일 때 가장 흔한 실수는 처음부터 모든 것을 테스트하려고 하는 것입니다. 화면, 상태 관리, API 호출, 라우팅, 빌드 설정까지 한 번에 다루려 하면 테스트 자체보다 환경 정리에 더 많은 시간을 쓰게 됩니다. 시작점은 작아야 합니다.
유틸 함수부터 시작하기
가장 먼저 볼 대상은 입력과 출력이 분명한 함수입니다. 가격 포맷, 날짜 포맷, 배열 정렬, 권한 판정, 폼 값 검증처럼 부작용이 적은 함수는 테스트 작성 비용이 낮습니다. 이런 테스트는 실패했을 때 원인을 찾기도 쉽고, 팀 안에서 테스트 문화를 설명하기에도 좋습니다.
- 입력과 출력이 명확한
function부터 테스트합니다. API호출이나 브라우저 상태에 강하게 묶인 코드는 뒤로 미룹니다.- 버그가 반복해서 발생한 로직은 우선순위를 높입니다.
- 테스트 이름은 구현 방식보다 기대 동작을 설명하도록 작성합니다.
컴포넌트와 사용자 동작으로 확장하기
유틸 함수 테스트에 익숙해졌다면 컴포넌트 테스트로 확장할 수 있습니다. React라면 @testing-library/react, Vue라면 @vue/test-utils 같은 도구를 함께 사용합니다. 이때 관심사는 컴포넌트 내부의 상태 변수 이름이 아니라 사용자가 보는 텍스트, 클릭 후 바뀌는 결과, 비활성화 상태 같은 외부 동작입니다.
예를 들어 SubmitButton 컴포넌트를 테스트한다면 isLoading이라는 내부 prop 자체보다 로딩 중에 버튼이 비활성화되는지, 화면에 적절한 문구가 보이는지를 확인하는 편이 좋습니다. 테스트가 사용자 관점에 가까울수록 리팩터링에도 덜 흔들립니다.
CI에서 자동 실행하기
테스트가 몇 개라도 생겼다면 로컬에서만 실행하지 말고 CI에 연결하는 것이 좋습니다. 최소한 npm run test:run이 pull request나 main branch push 시점에 실행되도록 구성하면, 깨진 테스트가 코드 리뷰 전에 드러납니다.
name: test
on:
pull_request:
push:
branches:
- main
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm run test:run
CI 설정까지 연결하면 테스트는 개인의 습관이 아니라 프로젝트의 기본 안전장치가 됩니다. 다만 처음부터 커버리지 기준을 높게 걸면 팀이 테스트를 부담스럽게 받아들일 수 있습니다. 처음에는 핵심 로직이 계속 통과하는지 확인하는 데 집중하고, 이후 coverage 설정을 단계적으로 추가하는 편이 낫습니다.
정리: Vite 프로젝트의 테스트 출발점으로서
Vite 프로젝트에서 Vitest를 도입하는 일은 거창한 테스트 전략을 세우는 것보다 훨씬 작게 시작할 수 있습니다. vitest를 설치하고, package.json에 실행 스크립트를 추가하고, 작은 함수 하나를 테스트하는 것만으로도 프로젝트는 이미 테스트 가능한 구조로 한 걸음 이동합니다.
node 환경과 jsdom 환경을 구분하고, vite.config.ts에서 필요한 설정만 추가하며, TypeScript 타입 설정을 확인하면 초반에 부딪히는 대부분의 문제를 줄일 수 있습니다. 중요한 것은 모든 코드를 한 번에 테스트하는 것이 아니라, 변경이 잦고 실수가 반복되는 부분부터 검증 가능한 형태로 만드는 것입니다.
Vitest는 Vite 프로젝트에서 테스트를 시작하기 위한 부담 낮은 출발점입니다. 작은 유틸 함수 테스트에서 시작해 컴포넌트 테스트와 CI 실행으로 확장하면, 테스트는 별도의 큰 작업이 아니라 개발 흐름 안에 자연스럽게 들어올 수 있습니다.