테스트 커버리지란 여러분이 작성한 테스트 코드들이 기존 애플리케이션 코드를 얼마나 충분하게(fully) 실행하고 검증했는지 그 비율을 측정하는 것을 말합니다. 이 지표를 통해 코드 내의 어떤 조건문, 로직 분기(branches), 함수, 그리고 변수들이 테스트 되었는지, 혹은 테스트되지 않고 누락되었는지를 명확하게 파악할 수 있죠.
커버리지 테스트는 테스트 도구가 주입된(instrumented) 코드를 돌려보면서 업계에서 인정하는 모범 사례 기준에 맞춰 코드를 샅샅이 살펴봅니다. 한마디로 여러분의 전체 테스트 스위트(test suite)의 품질을 끌어올려 주는 QA의 든든한 마지막 방어선이라고 할 수 있어요.
프로젝트마다 생성되는 커버리지 리포트의 모습은 조금씩 다르겠지만, 여기서 꼭 챙겨 봐야 할 핵심 포인트는 딱 두 가지입니다:
Vitest 애드온(Vitest addon)을 사용해서 컴포넌트 테스트를 실행하면, 이 커버리지 리포트를 짠! 하고 생성할 수 있습니다. 결과는 스토리북 화면 사이드바의 테스팅 위젯(testing widget)에 요약되어 나타나며, 테스트된 스토리들이 전체 구문(statements)을 몇 퍼센트나 커버했는지 보여준답니다.

ℹ️ 만약 프로젝트 환경상 Vitest 애드온을 사용할 수 없다면, 테스트 러너(test-runner)를 활용해서도 코드 커버리지를 생성할 수 있어요. 설정 방법은 테스트 러너 공식 문서의 '코드 커버리지 생성하기(generate code coverage)' 섹션을 참고해 주시면 됩니다.
커버리지 기능은 Vitest 애드온에 아예 내장되어 있어요. 기능을 켜두기만 하면 프로젝트의 컴포넌트 테스트가 돌 때마다 알아서 커버리지를 계산해 줍니다. 커버리지 기능을 활성화하려면 테스팅 위젯에 있는 'coverage' 체크박스에 체크만 해주시면 끝이에요.

단, 커버리지를 성공적으로 계산하기 전에 먼저 여러분이 선택한 커버리지 제공자(coverage provider)에 맞는 지원 패키지를 하나 설치해야 할 수도 있습니다:
# v8을 사용하는 경우
npm install --save-dev @vitest/coverage-v8
# istanbul을 사용하는 경우
npm install --save-dev @vitest/coverage-istanbul
커버리지 기능이 Vitest 애드온에 찰떡같이 내장되어 있기 때문에, 테스트를 실행하는 곳이라면 어디서든 이 커버리지 결과를 확인할 수 있습니다.
스토리북 UI에서 커버리지 기능을 켜고 테스트를 실행하면, 테스팅 위젯 안에 커버리지 리포트 요약본이 나타납니다. 여기서 테스트된 스토리들의 구문 커버리지 비율은 물론이고, 이 비율이 미리 설정해 둔 워터마크(watermarks, 목표 기준치)를 달성했는지도 한눈에 확인할 수 있어요.
뿐만 아니라, 로컬에서 실행 중인 스토리북 주소 뒤에 /coverage/index.html을 붙여서 접속하시면 아주 상세한 전체 커버리지 리포트 페이지를 볼 수 있습니다.

이 리포트는 클릭도 됩니다! 특정 컴포넌트를 클릭하고 들어가면, 소스 코드 위에서 정확히 어느 부분이 테스트로 덮여있고(covered), 어느 부분이 비어있는지(uncovered) 아주 직관적으로 확인할 수 있답니다.

⚠️ 주의: 스토리북 UI에 표시되는 커버리지 결과에는 세 가지 중요한 한계점이 있으니 꼭 기억해 주세요:
Storybook Test의 다른 기능들처럼 커버리지 역시 Vitest를 뼈대로 삼고 있기 때문에, Vitest CLI 명령어를 사용해서도 훌륭한 커버리지 리포트를 뽑아낼 수 있어요.
예를 들어, package.json에 아래처럼 테스트 스크립트를 세팅해 두셨다고 가정해 볼게요:
{
"scripts": {
"test-storybook": "vitest --project=storybook"
}
}
그러면 터미널에서 이렇게 명령어를 쳐서 커버리지 리포트를 쫙 뽑아낼 수 있습니다:
npm run test-storybook -- --coverage

이 커버리지 리포트 결과물은 프로젝트에 미리 설정된 커버리지 리포트 저장 폴더(coverage reports directory) (기본값은 ./coverage 폴더) 안에 안전하게 저장됩니다.
💡 잠깐! 방금 터미널에서 실행한 위 명령어는 오직 '작성된 스토리들'에 대한 커버리지만 계산하고 전체 코드베이스는 무시한다는 점을 기억하세요. 가장 정확하고 이상적인 커버리지는 프로젝트 내의 모든 테스트(스토리 + 일반 테스트)를 싹 다 합쳐서 계산할 때 나옵니다. 프로젝트 전체 테스트에 대한 커버리지를 구하고 싶다면, 터미널에서 그냥 아래처럼 입력하시면 됩니다:
npx vitest --coverage
Vitest가 지원하는 IDE 통합 기능(IDE integrations)을 활용하면 커버리지 결과를 에디터(VSCode 등) 안에서 바로바로 확인할 수도 있습니다. 코드를 짜면서 커버리지 수치와 하이라이트를 실시간으로 보는 거죠!

ℹ️ 에디터에서 보여주는 이 커버리지 결과에는 스토리를 포함한 프로젝트 내의 모든 테스트 결과가 합산되어 나타납니다.
CI(지속적 통합) 파이프라인 안에서 커버리지 리포트를 생성하려면 앞서 배운 CLI 명령어를 사용하시면 됩니다.
예를 들어, GitHub Actions 워크플로우를 구성한다면 대략 이런 모습이 될 거예요:
name: Storybook Tests
on: push
jobs:
test:
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20.x'
- name: Install dependencies
run: yarn
# 👇 스토리북 테스트를 포함한 모든 Vitest 테스트를 싹 다 실행합니다!
- name: Run tests
run: yarn test --coverage
💡 여기서 질문! 왜 스토리북 테스트 전용 명령어(yarn test-storybook)를 안 쓰고 전체 테스트 명령어(yarn test)를 썼을까요? 바로 CI 환경의 결과물에서는 스토리에만 국한된 반쪽짜리 커버리지보다는, 프로젝트 전체를 아우르는 가장 빵빵하고 포괄적인(comprehensive) 커버리지 리포트를 보는 것이 훨씬 의미가 있기 때문입니다. (스토리북 전용 커버리지는 로컬 개발할 때나 스토리북 UI 안에서 보는 걸로 충분하니까요!)
CI 환경 테스팅에 대한 더 깊이 있는 내용은 전용 가이드(dedicated guide)에서 확인해 보세요.
Vitest 설정 파일(vitest.config.ts)에서 coverage.provider 옵션을 만져주면, 커버리지를 계산할 엔진(provider)으로 v8 (기본값)을 쓸지 아니면 Istanbul을 쓸지 선택할 수 있습니다:
import { defineConfig } from 'vitest/config';
export default defineConfig({
// ...
test: {
// ...
coverage: {
// ...
provider: 'istanbul', // 'v8'이 기본값입니다
},
},
});
두 커버리지 제공자 모두 워터마크(watermarks) 설정을 지원합니다. 일종의 '합격선' 같은 건데요. 하위 워터마크(low watermark)는 테스트를 통과하기 위한 최소한의 커버리지 수치이고, 상위 워터마크(high watermark)는 "와, 이 정도면 훌륭해!"라고 인정할 만한 목표 수치입니다. 만약 커버리지가 이 두 수치 사이에 있다면 나쁘진 않지만 베스트는 아닌, 그런 상태인 거죠.
테스팅 위젯의 커버리지 요약 부분을 보면 이 워터마크 달성 여부를 색깔로 알려줍니다. 하위 워터마크에 못 미치면 아이콘이 빨간색 🔴, 두 워터마크 사이면 주황색 🟠, 상위 워터마크를 훌쩍 넘기면 기분 좋은 초록색 🟢으로 표시된답니다.
이 워터마크 수치들도 Vitest 설정 파일에서 여러분 맘대로 바꿀 수 있어요:
import { defineConfig } from 'vitest/config';
export default defineConfig({
// ...
test: {
// ...
coverage: {
// ...
watermarks: {
// 아래는 Vitest의 기본값들입니다
statements: [50, 80],
},
},
},
});
커버리지와 관련된 더 무궁무진하고 다양한 설정 옵션들은 Vitest 공식 문서에서 확인하실 수 있습니다.
단, 스토리북 UI 안에서 커버리지를 계산할 때는 내부 동작을 위해 다음 Vitest 옵션들은 설정하더라도 무시(ignored)되니 참고해 주세요:
enabledcleancleanOnRerunreportOnFailurereporterreportsDirectory더 유용한 테스팅 관련 자료들