web-testing-vitest
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseVitest Test Runner Patterns
Vitest测试运行器模式
Quick Guide: Vitest is a fast, Vite-native test runner. Use/describe/itfor test structure,expectfor mocks,vi.fn()for module mocking,vi.mock()for spying. Co-locate tests with code. Use network-level API mocking over module-level mocks. Vitest v4 is current stable (requires Vite 6+, Node 20+).vi.spyOn()
<critical_requirements>
快速指南: Vitest是一款快速的、原生支持Vite的测试运行器。使用/describe/it构建测试结构,expect创建Mock,vi.fn()进行模块Mock,vi.mock()实现监听。将测试与代码放在同一位置。优先使用网络级API Mock而非模块级Mock。Vitest v4为当前稳定版本(要求Vite 6+、Node 20+)。vi.spyOn()
<critical_requirements>
CRITICAL: Before Using This Skill
重要须知:使用本技能前
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,, named constants)import type
(You MUST co-locate tests with code in feature-based structure - NOT in separate test directories)
(You MUST use network-level API mocking - NOT module-level mocks where possible)
(You MUST use named constants for test data - no magic strings or numbers in test files)
(You MUST use for mocks and for spying - NEVER manually replace functions)
vi.fn()vi.spyOn()(You MUST use the v3+ test options syntax: - NOT as third argument)
test("name", { timeout: 10_000 }, () => {})</critical_requirements>
Auto-detection: Vitest, vi.fn, vi.mock, vi.spyOn, describe, it, expect, test, beforeEach, afterEach, vi.useFakeTimers, vitest.config, defineConfig, coverage, snapshot, mockResolvedValue, mockRejectedValue
When to use:
- Configuring and running tests with Vitest
- Writing unit tests for pure functions
- Writing integration tests with network-level mocking
- Mocking modules, functions, and timers
- Snapshot testing
- Configuring coverage, workspaces, and projects
When NOT to use:
- E2E browser testing (use your E2E testing tool)
- Component rendering and querying (use your component testing library)
- Testing third-party library behavior (library already has tests)
- Testing TypeScript compile-time guarantees (TypeScript already enforces)
Key patterns covered:
- Test structure and organization (describe, it, expect)
- Mocking (vi.fn, vi.mock, vi.spyOn, vi.mockObject)
- Fake timers (vi.useFakeTimers, vi.advanceTimersByTime)
- Network-level API mocking for integration tests
- Feature-based test organization (co-located with code)
- Configuration (vitest.config, projects, coverage)
- Vitest v3/v4 migration and breaking changes
Detailed Resources:
- examples/core.md - Unit test examples, pure functions
- examples/integration.md - Integration tests with network-level mocking
- examples/anti-patterns.md - What NOT to test
- reference.md - Vitest v3/v4 migration notes, decision frameworks
<philosophy>
所有代码必须遵循CLAUDE.md中的项目约定(短横线命名、命名导出、导入顺序、、命名常量)import type
(必须将测试与代码放在基于功能的结构中,而非单独的测试目录)
(必须使用网络级API Mock,尽可能避免模块级Mock)
(必须为测试数据使用命名常量,测试文件中不能有魔法字符串或数字)
(必须使用创建Mock,实现监听,绝不能手动替换函数)
vi.fn()vi.spyOn()(必须使用v3+版本的测试选项语法:,不能将选项作为第三个参数)
test("name", { timeout: 10_000 }, () => {})</critical_requirements>
自动检测项: Vitest, vi.fn, vi.mock, vi.spyOn, describe, it, expect, test, beforeEach, afterEach, vi.useFakeTimers, vitest.config, defineConfig, coverage, snapshot, mockResolvedValue, mockRejectedValue
适用场景:
- 使用Vitest配置和运行测试
- 为纯函数编写单元测试
- 通过网络级Mock编写集成测试
- Mock模块、函数和计时器
- 快照测试
- 配置覆盖率、工作区和项目
不适用场景:
- E2E浏览器测试(使用你的E2E测试工具)
- 组件渲染和查询(使用你的组件测试库)
- 测试第三方库的行为(库本身已有测试)
- 测试TypeScript编译时保证(TypeScript已强制执行)
涵盖的核心模式:
- 测试结构与组织(describe, it, expect)
- Mock(vi.fn, vi.mock, vi.spyOn, vi.mockObject)
- 假计时器(vi.useFakeTimers, vi.advanceTimersByTime)
- 用于集成测试的网络级API Mock
- 基于功能的测试组织(与代码同位置)
- 配置(vitest.config, projects, coverage)
- Vitest v3/v4迁移与破坏性变更
详细资源:
- examples/core.md - 单元测试示例、纯函数
- examples/integration.md - 带网络级Mock的集成测试
- examples/anti-patterns.md - 不应测试的内容
- reference.md - Vitest v3/v4迁移说明、决策框架
<philosophy>
Philosophy
理念
Vitest is a Vite-native test runner designed for speed and developer experience. It provides Jest-compatible APIs with native ESM support, TypeScript out of the box, and Vite's transform pipeline.
Core Principles:
- Co-locate tests with code - Tests live next to the code they test for discoverability and maintenance
- Network-level mocking over module mocking - Mock at the HTTP boundary, not at import boundaries
- Named constants for all test data - No magic strings or numbers in test files
- Test behavior, not implementation - Focus on inputs and outputs, not internal state
- Fast feedback loops - Leverage Vitest's HMR-based watch mode for instant re-runs
When to use Vitest:
- Unit testing pure functions (business logic, utilities, formatters)
- Integration testing with network-level API mocking
- Snapshot testing for serializable outputs
- Any test that doesn't require a real browser
When NOT to use Vitest:
- Browser-based E2E testing (use your E2E testing tool)
- Visual regression testing (use your visual testing tool)
<patterns>
Vitest是一款原生支持Vite的测试运行器,旨在提升速度和开发者体验。它提供与Jest兼容的API,原生支持ESM,开箱即用TypeScript,并集成Vite的转换管道。
核心原则:
- 测试与代码同位置 - 测试与被测代码放在一起,便于查找和维护
- 优先网络级Mock而非模块级Mock - 在HTTP边界进行Mock,而非导入边界
- 所有测试数据使用命名常量 - 测试文件中不能有魔法字符串或数字
- 测试行为而非实现 - 关注输入和输出,而非内部状态
- 快速反馈循环 - 利用Vitest基于HMR的监听模式实现即时重跑
Vitest适用场景:
- 纯函数的单元测试(业务逻辑、工具函数、格式化器)
- 带网络级API Mock的集成测试
- 可序列化输出的快照测试
- 任何不需要真实浏览器的测试
Vitest不适用场景:
- 基于浏览器的E2E测试(使用你的E2E测试工具)
- 视觉回归测试(使用你的视觉测试工具)
<patterns>
Core Patterns
核心模式
Pattern 1: Unit Testing Pure Functions
模式1:纯函数单元测试
Write unit tests for pure functions with no side effects. Focus on clear input/output behavior.
What to test:
- Pure functions with clear input -> output
- Business logic calculations (pricing, taxes, discounts)
- Data transformations and formatters
- Edge cases and boundary conditions
See examples/core.md for pure function test examples.
为无副作用的纯函数编写单元测试,聚焦清晰的输入/输出行为。
测试内容:
- 输入输出清晰的纯函数
- 业务逻辑计算(定价、税费、折扣)
- 数据转换与格式化
- 边缘情况与边界条件
查看examples/core.md获取纯函数测试示例。
Pattern 2: Integration Testing with Network-Level Mocking
模式2:带网络级Mock的集成测试
Use Vitest with network-level API mocking to test components with their API integration layer.
When Integration Tests Make Sense:
- Component behavior in isolation (form validation, UI state)
- Testing edge cases that are hard to reproduce in E2E
- Development workflow (faster than spinning up full stack)
Key Pattern:
- Tests in directories co-located with code
__tests__/ - Network-level API mocking (intercepts HTTP requests)
- Centralized mock data in shared package
- Test all states: loading, empty, error, success
See examples/integration.md for integration test examples.
结合Vitest与网络级API Mock,测试带有API集成层的组件。
集成测试适用场景:
- 组件的独立行为(表单验证、UI状态)
- 测试E2E中难以复现的边缘情况
- 开发工作流(比启动全栈更快)
核心模式:
- 测试放在与代码同位置的目录中
__tests__/ - 网络级API Mock(拦截HTTP请求)
- 共享包中的集中式Mock数据
- 测试所有状态:加载中、空数据、错误、成功
查看examples/integration.md获取集成测试示例。
Pattern 3: Feature-Based Test Organization
模式3:基于功能的测试组织
Co-locate tests with code in feature-based structure. Tests live next to what they test.
Direct Co-location (Recommended):
src/
features/
auth/
components/
login-form.tsx
login-form.test.tsx # Test next to component
hooks/
use-auth.ts
use-auth.test.ts # Test next to hookAlternative: Subdirectories:
__tests__/src/features/auth/
components/
login-form.tsx
__tests__/
login-form.test.tsxE2E Test Organization:
tests/
e2e/
auth/
login-flow.spec.ts
register-flow.spec.ts
checkout/
checkout-flow.spec.tsFile Naming Convention:
- /
*.test.tsxfor unit and integration tests*.test.ts
Choose one pattern and be consistent across the codebase.
</patterns>
<red_flags>
将测试与代码放在基于功能的结构中,测试与被测内容相邻。
直接同位置(推荐):
src/
features/
auth/
components/
login-form.tsx
login-form.test.tsx # 测试与组件同位置
hooks/
use-auth.ts
use-auth.test.ts # 测试与Hook同位置替代方案:子目录:
__tests__/src/features/auth/
components/
login-form.tsx
__tests__/
login-form.test.tsxE2E测试组织:
tests/
e2e/
auth/
login-flow.spec.ts
register-flow.spec.ts
checkout/
checkout-flow.spec.ts文件命名约定:
- /
*.test.tsx用于单元测试和集成测试*.test.ts
选择一种模式并在整个代码库中保持一致。
</patterns>
<red_flags>
RED FLAGS
警示事项
High Priority Issues:
- Module-level mocking () instead of network-level - breaks when import structure changes, doesn't test serialization
vi.mock - Only testing happy paths - error states go untested until users report them
- Not using named constants for test data - magic strings and numbers make tests unreadable
Medium Priority Issues:
- Mocks that don't match real API - tests pass but production fails because mocks drifted
- Complex mocking setup - simplify or test at a higher level
- Not resetting mocks between tests - causes cross-test pollution
Gotchas & Edge Cases:
- Network mock handlers are typically global - reset handlers after each test to prevent pollution
- Vitest v3+: Test options must be second argument: NOT
test("name", { timeout: 10_000 }, () => {})test("name", () => {}, { timeout: 10_000 }) - Vitest v4: Multiple mock behavior changes (getMockName, restoreAllMocks, automocked getters) - see reference.md for full v4 migration notes
- starts at
vi.fn().mock.invocationCallOrderin v4 instead of10 - only affects manual spies in v4, not automocks - use
vi.restoreAllMocks()for full resetvi.resetAllMocks()
</red_flags>
<critical_reminders>
高优先级问题:
- 使用模块级Mock()而非网络级Mock - 导入结构变化时会失效,无法测试序列化
vi.mock - 仅测试正常流程 - 错误状态直到用户反馈才会被发现
- 不为测试数据使用命名常量 - 魔法字符串和数字导致测试难以阅读
中优先级问题:
- Mock与真实API不匹配 - 测试通过但生产环境失败,因为Mock已偏离
- 复杂的Mock设置 - 简化或在更高层级测试
- 测试间未重置Mock - 导致测试间污染
陷阱与边缘情况:
- 网络Mock处理器通常是全局的 - 每次测试后重置处理器以防止污染
- Vitest v3+: 测试选项必须作为第二个参数:而非
test("name", { timeout: 10_000 }, () => {})test("name", () => {}, { timeout: 10_000 }) - Vitest v4: 多项Mock行为变更(getMockName、restoreAllMocks、自动Mock的getter)- 查看reference.md获取完整的v4迁移说明
- 在v4中从
vi.fn().mock.invocationCallOrder开始计数,而非10 - 在v4中仅影响手动创建的监听,不影响自动Mock - 使用
vi.restoreAllMocks()进行完全重置vi.resetAllMocks()
</red_flags>
<critical_reminders>
CRITICAL REMINDERS
重要提醒
All code must follow project conventions in CLAUDE.md
(You MUST co-locate tests with code in feature-based structure - NOT in separate test directories)
(You MUST use network-level API mocking - NOT module-level mocks where possible)
(You MUST use named constants for test data - no magic strings or numbers in test files)
(You MUST use for mocks and for spying - NEVER manually replace functions)
vi.fn()vi.spyOn()(You MUST use the v3+ test options syntax: - NOT as third argument)
test("name", { timeout: 10_000 }, () => {})Failure to follow these rules will result in fragile tests that break on refactoring and false confidence from poorly structured test suites.
</critical_reminders>
所有代码必须遵循CLAUDE.md中的项目约定
(必须将测试与代码放在基于功能的结构中,而非单独的测试目录)
(必须使用网络级API Mock,尽可能避免模块级Mock)
(必须为测试数据使用命名常量,测试文件中不能有魔法字符串或数字)
(必须使用创建Mock,实现监听,绝不能手动替换函数)
vi.fn()vi.spyOn()(必须使用v3+版本的测试选项语法:,不能将选项作为第三个参数)
test("name", { timeout: 10_000 }, () => {})不遵循这些规则将导致测试脆弱,重构时易失效,且测试套件结构不佳会带来错误的信心。
</critical_reminders>