web-testing-vitest

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Vitest Test Runner Patterns

Vitest测试运行器模式

Quick Guide: Vitest is a fast, Vite-native test runner. Use
describe
/
it
/
expect
for test structure,
vi.fn()
for mocks,
vi.mock()
for module mocking,
vi.spyOn()
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+).

<critical_requirements>
快速指南: Vitest是一款快速的、原生支持Vite的测试运行器。使用
describe
/
it
/
expect
构建测试结构,
vi.fn()
创建Mock,
vi.mock()
进行模块Mock,
vi.spyOn()
实现监听。将测试与代码放在同一位置。优先使用网络级API Mock而非模块级Mock。Vitest v4为当前稳定版本(要求Vite 6+、Node 20+)。

<critical_requirements>

CRITICAL: Before Using This Skill

重要须知:使用本技能前

All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,
import type
, named constants)
(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
vi.fn()
for mocks and
vi.spyOn()
for spying - NEVER manually replace functions)
(You MUST use the v3+ test options syntax:
test("name", { timeout: 10_000 }, () => {})
- NOT as third argument)
</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)
(必须为测试数据使用命名常量,测试文件中不能有魔法字符串或数字)
(必须使用
vi.fn()
创建Mock,
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:
  1. Co-locate tests with code - Tests live next to the code they test for discoverability and maintenance
  2. Network-level mocking over module mocking - Mock at the HTTP boundary, not at import boundaries
  3. Named constants for all test data - No magic strings or numbers in test files
  4. Test behavior, not implementation - Focus on inputs and outputs, not internal state
  5. 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)
</philosophy>
<patterns>
Vitest是一款原生支持Vite的测试运行器,旨在提升速度和开发者体验。它提供与Jest兼容的API,原生支持ESM,开箱即用TypeScript,并集成Vite的转换管道。
核心原则:
  1. 测试与代码同位置 - 测试与被测代码放在一起,便于查找和维护
  2. 优先网络级Mock而非模块级Mock - 在HTTP边界进行Mock,而非导入边界
  3. 所有测试数据使用命名常量 - 测试文件中不能有魔法字符串或数字
  4. 测试行为而非实现 - 关注输入和输出,而非内部状态
  5. 快速反馈循环 - 利用Vitest基于HMR的监听模式实现即时重跑
Vitest适用场景:
  • 纯函数的单元测试(业务逻辑、工具函数、格式化器)
  • 带网络级API Mock的集成测试
  • 可序列化输出的快照测试
  • 任何不需要真实浏览器的测试
Vitest不适用场景:
  • 基于浏览器的E2E测试(使用你的E2E测试工具)
  • 视觉回归测试(使用你的视觉测试工具)
</philosophy>
<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
    __tests__/
    directories co-located with code
  • 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 hook
Alternative:
__tests__/
Subdirectories:
src/features/auth/
  components/
    login-form.tsx
    __tests__/
      login-form.test.tsx
E2E Test Organization:
tests/
  e2e/
    auth/
      login-flow.spec.ts
      register-flow.spec.ts
    checkout/
      checkout-flow.spec.ts
File Naming Convention:
  • *.test.tsx
    /
    *.test.ts
    for unit and integration tests
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.tsx
E2E测试组织:
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 (
    vi.mock
    ) instead of network-level - breaks when import structure changes, doesn't test serialization
  • 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:
    test("name", { timeout: 10_000 }, () => {})
    NOT
    test("name", () => {}, { timeout: 10_000 })
  • Vitest v4: Multiple mock behavior changes (getMockName, restoreAllMocks, automocked getters) - see reference.md for full v4 migration notes
  • vi.fn().mock.invocationCallOrder
    starts at
    1
    in v4 instead of
    0
  • vi.restoreAllMocks()
    only affects manual spies in v4, not automocks - use
    vi.resetAllMocks()
    for full reset
</red_flags>

<critical_reminders>
高优先级问题:
  • 使用模块级Mock(
    vi.mock
    )而非网络级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迁移说明
  • vi.fn().mock.invocationCallOrder
    在v4中从
    1
    开始计数,而非
    0
  • vi.restoreAllMocks()
    在v4中仅影响手动创建的监听,不影响自动Mock - 使用
    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
vi.fn()
for mocks and
vi.spyOn()
for spying - NEVER manually replace functions)
(You MUST use the v3+ test options syntax:
test("name", { timeout: 10_000 }, () => {})
- NOT as third argument)
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)
(必须为测试数据使用命名常量,测试文件中不能有魔法字符串或数字)
(必须使用
vi.fn()
创建Mock,
vi.spyOn()
实现监听,绝不能手动替换函数)
(必须使用v3+版本的测试选项语法:
test("name", { timeout: 10_000 }, () => {})
,不能将选项作为第三个参数)
不遵循这些规则将导致测试脆弱,重构时易失效,且测试套件结构不佳会带来错误的信心。
</critical_reminders>