구현할 기능
apps/web에 Vitest 기반 유닛 테스트 환경을 세팅한다.
현재 Playwright e2e로 주요 사용자 플로우는 덮고 있지만, 계산·판정 로직에는 테스트가 하나도 없다.
담기 개수 계산(getActiveBasketCount), URL 파싱(extractUrlFromText), 뒤로가기 히스토리 추적처럼 특정 입력에서만 조용히 다른 값을 내는 버그가 반복해서 났고, 전부 개발 중이 아니라 실사용 중에 발견됐다.
에러가 나지 않고 값만 어긋나는 종류라 e2e·타입체크로는 잡히지 않는다.
이 이슈에서는 환경 설정 + 동작 확인용 샘플 테스트 1개까지만 다루고,실제 테스트 작성은 대상별 후속 이슈로 분리한다.
왜 Vitest인가
- ESM/TS 추가 설정이 거의 없이 동작 (Next 16 + TS 5.9 환경 그대로)
@/* 별칭을 config alias로 그대로 연결 가능
- 스크립트 이름이
test:e2e(Playwright)와 겹치지 않아 test로 깔끔하게 분리됨
작업 상세 내용
1. 의존성 · 설정
2. 파일 컨벤션 확정
3. 스크립트 · 파이프라인
4. 동작 확인
확인이 필요한 사항
e2e와의 역할 분담
- Playwright: 클릭 → 화면 전환 같은 사용자 플로우 + 대표적인 분기 몇 개(에러 화면, 빈 상태, 비활성화) — 지금처럼 유지
- Vitest: 그 분기를 만들어내는 계산 로직의 경계값을 촘촘하게
구현할 기능
apps/web에 Vitest 기반 유닛 테스트 환경을 세팅한다.현재 Playwright e2e로 주요 사용자 플로우는 덮고 있지만, 계산·판정 로직에는 테스트가 하나도 없다.
담기 개수 계산(
getActiveBasketCount), URL 파싱(extractUrlFromText), 뒤로가기 히스토리 추적처럼 특정 입력에서만 조용히 다른 값을 내는 버그가 반복해서 났고, 전부 개발 중이 아니라 실사용 중에 발견됐다.에러가 나지 않고 값만 어긋나는 종류라 e2e·타입체크로는 잡히지 않는다.
이 이슈에서는 환경 설정 + 동작 확인용 샘플 테스트 1개까지만 다루고,실제 테스트 작성은 대상별 후속 이슈로 분리한다.
왜 Vitest인가
@/*별칭을 config alias로 그대로 연결 가능test:e2e(Playwright)와 겹치지 않아test로 깔끔하게 분리됨작업 상세 내용
1. 의존성 · 설정
apps/web에vitest설치 (devDependency)apps/web/vitest.config.ts추가test.environment: 'node'— 순수 함수 대상이라 jsdom 불필요test.include: ['src/**/*.test.ts']test.exclude에e2e/**포함 — Playwright(e2e/**/*.spec.ts)와 수집 범위가 절대 겹치지 않도록resolve.alias로@/→./src연결 (별칭 하나만 필요하므로vite-tsconfig-paths같은 추가 플러그인 없이 직접 지정)2. 파일 컨벤션 확정
*.test.ts, Playwright는*.spec.tssrc/utils/extractUrl.ts→src/utils/extractUrl.test.ts3. 스크립트 · 파이프라인
apps/web/package.json:test(vitest run),test:watch(vitest) 추가package.json:test→turbo run test추가turbo.json에testtask 등록.github/workflows/ci.yml— 기존Lint, Type Checkjob에Unit Test스텝 추가(수 초 수준이라 별도 job으로 분리하지 않음. e2e job은 지금 구조 유지)
4. 동작 확인
getActiveBasketCount경계값 (실제 버그가 났던 지점)pnpm test로컬 통과 확인pnpm lint/pnpm check-types가 테스트 파일에서도 통과하는지 확인(
apps/web/tsconfig.json의include가**/*.ts라 테스트 파일도 타입체크 대상에 포함됨)확인이 필요한 사항
globals: true로describe/it/expect를 전역 사용할지, 매 파일에서import { describe, it, expect } from 'vitest'로 명시할지→ 전역을 쓰면
tsconfig에types: ["vitest/globals"]추가가 필요하다. 명시 import 쪽이 의존성이 드러나서 팀 컨벤션과 더 맞아 보이는데 의견 부탁@vitest/coverage-v8) 도입 여부 — 지금은 커버리지 수치를 게이트로 쓸 단계가 아니라고 보고 이번 이슈에서는 제외하는 방향으로 제안e2e와의 역할 분담