vitest-3-features

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

🚨 CRITICAL GUIDELINES

🚨 重要指南

Windows File Path Requirements

Windows 文件路径要求

MANDATORY: Always Use Backslashes on Windows for File Paths
When using Edit or Write tools on Windows, you MUST use backslashes (
\
) in file paths, NOT forward slashes (
/
).
Examples:
  • ❌ WRONG:
    D:/repos/project/file.tsx
  • ✅ CORRECT:
    D:\repos\project\file.tsx
This applies to:
  • Edit tool file_path parameter
  • Write tool file_path parameter
  • All file operations on Windows systems
强制性要求:在Windows系统中操作文件路径时必须使用反斜杠(
\
),而非正斜杠(
/
在Windows系统上使用Edit或Write工具时,文件路径必须使用反斜杠(
\
),不能使用正斜杠(
/
)。
示例:
  • ❌ 错误写法:
    D:/repos/project/file.tsx
  • ✅ 正确写法:
    D:\repos\project\file.tsx
这适用于:
  • Edit工具的file_path参数
  • Write工具的file_path参数
  • Windows系统上的所有文件操作

Documentation Guidelines

文档编写指南

NEVER create new documentation files unless explicitly requested by the user.
  • Priority: Update existing README.md files rather than creating new documentation
  • Repository cleanliness: Keep repository root clean - only README.md unless user requests otherwise
  • Style: Documentation should be concise, direct, and professional - avoid AI-generated tone
  • User preference: Only create additional .md files when user specifically asks for documentation

除非用户明确要求,否则绝不创建新的文档文件。
  • 优先级:优先更新现有README.md文件,而非创建新文档
  • 仓库整洁性:保持仓库根目录整洁——除非用户要求,否则仅保留README.md
  • 风格:文档应简洁、直接、专业——避免AI生成的冗余语气
  • 用户偏好:仅在用户明确要求编写文档时,才创建额外的.md文件

Vitest 3.x Features and Best Practices (2025)

Vitest 3.x 功能特性与最佳实践(2025)

Overview

概述

Vitest 3.0 was released in January 2025 with major improvements to reporting, browser testing, watch mode, and developer experience. This skill provides comprehensive knowledge of Vitest 3.x features and modern testing patterns.
Vitest 3.0于2025年1月发布,在测试报告、浏览器测试、监听模式和开发者体验方面有重大改进。本指南全面介绍了Vitest 3.x的功能特性和现代测试模式。

Major Features in Vitest 3.0+

Vitest 3.0+ 主要功能特性

1. Annotation API (Vitest 3.2+)

1. 注解API(Vitest 3.2+)

The annotation API allows you to add custom metadata, messages, and attachments to any test, visible in UI, HTML, JUnit, TAP, and GitHub Actions reporters.
Usage:
javascript
import { test, expect } from 'vitest';

test('user authentication', async ({ task }) => {
  // Add custom annotation
  task.meta.annotation = {
    message: 'Testing OAuth2 flow with external provider',
    attachments: [
      { name: 'config', content: JSON.stringify(oauthConfig) }
    ]
  };

  const result = await authenticateUser(credentials);
  expect(result.token).toBeDefined();
});
Use Cases:
  • Document complex test scenarios
  • Attach debug information
  • Link to external resources (tickets, docs)
  • Add performance metrics
  • Track test metadata for reporting
注解API允许你为任意测试添加自定义元数据、消息和附件,这些内容会在UI、HTML、JUnit、TAP和GitHub Actions报告器中显示。
使用示例:
javascript
import { test, expect } from 'vitest';

test('用户认证', async ({ task }) => {
  // 添加自定义注解
  task.meta.annotation = {
    message: '测试与外部服务商的OAuth2流程',
    attachments: [
      { name: '配置', content: JSON.stringify(oauthConfig) }
    ]
  };

  const result = await authenticateUser(credentials);
  expect(result.token).toBeDefined();
});
适用场景:
  • 记录复杂测试场景
  • 附加调试信息
  • 关联外部资源(工单、文档)
  • 添加性能指标
  • 跟踪测试元数据用于报告

2. Line Number Filtering

2. 行号过滤

Run specific tests by their line number in the file, enabling precise test execution from IDEs.
CLI Usage:
bash
undefined
通过文件中的行号运行特定测试,支持从IDE中精准执行测试。
CLI使用示例:
bash
undefined

Run test at specific line

运行指定行的测试

vitest run tests/user.test.js:42
vitest run tests/user.test.js:42

Run multiple tests by line

运行多个指定行的测试

vitest run tests/user.test.js:42 tests/user.test.js:67
vitest run tests/user.test.js:42 tests/user.test.js:67

Works with ranges

支持行号范围

vitest run tests/user.test.js:42-67

**IDE Integration:**
- VS Code: Click line number gutter
- JetBrains IDEs: Run from context menu
- Enables "run test at cursor" functionality
vitest run tests/user.test.js:42-67

**IDE集成:**
- VS Code:点击行号 gutter 区域
- JetBrains IDE:从右键菜单运行
- 支持“运行光标所在行的测试”功能

3. Enhanced Watch Mode

3. 增强型监听模式

Smarter and more responsive watch mode with improved change detection.
Features:
  • Detects changes more accurately
  • Only re-runs affected tests
  • Faster rebuild times
  • Better file watching on Windows
  • Reduced false positives
Configuration:
javascript
export default defineConfig({
  test: {
    watch: true,
    watchExclude: ['**/node_modules/**', '**/dist/**'],
    // New in 3.0: More intelligent caching
    cache: {
      dir: '.vitest/cache'
    }
  }
});
更智能、响应更迅速的监听模式,改进了变更检测能力。
功能特性:
  • 更准确的变更检测
  • 仅重新运行受影响的测试
  • 更快的重建速度
  • 优化了Windows系统上的文件监听
  • 减少误触发
配置示例:
javascript
export default defineConfig({
  test: {
    watch: true,
    watchExclude: ['**/node_modules/**', '**/dist/**'],
    // 3.0新增:更智能的缓存
    cache: {
      dir: '.vitest/cache'
    }
  }
});

4. Improved Test Reporting

4. 改进的测试报告

Complete overhaul of test run reporting with reduced flicker and clearer output.
Reporter API Changes:
javascript
// Custom reporter with new lifecycle
export default class CustomReporter {
  onInit(ctx) {
    // Called once at start
  }

  onTestStart(test) {
    // More reliable test start hook
  }

  onTestComplete(test) {
    // Includes full test metadata
  }

  onFinished(files, errors) {
    // Final results with all context
  }
}
Benefits:
  • Less terminal flicker during test runs
  • Clearer test status indicators
  • Better error formatting
  • Improved progress tracking
全面重构了测试运行报告,减少了终端闪烁,输出更清晰。
报告器API变更:
javascript
// 带有新生命周期的自定义报告器
export default class CustomReporter {
  onInit(ctx) {
    // 在启动时调用一次
  }

  onTestStart(test) {
    // 更可靠的测试启动钩子
  }

  onTestComplete(test) {
    // 包含完整的测试元数据
  }

  onFinished(files, errors) {
    // 包含所有上下文的最终结果
  }
}
优势:
  • 测试运行期间终端闪烁更少
  • 更清晰的测试状态标识
  • 更友好的错误格式化
  • 改进的进度跟踪

5. Workspace Configuration Simplification

5. 简化的工作区配置

No need for separate workspace files - define projects directly in config.
Old Way (Vitest 2.x):
javascript
// vitest.workspace.js
export default ['packages/*'];
New Way (Vitest 3.0):
javascript
// vitest.config.js
export default defineConfig({
  test: {
    workspace: [
      {
        test: {
          name: 'unit',
          include: ['tests/unit/**/*.test.js']
        }
      },
      {
        test: {
          name: 'integration',
          include: ['tests/integration/**/*.test.js']
        }
      }
    ]
  }
});
无需单独的工作区文件,可直接在主配置中定义项目。
旧方式(Vitest 2.x):
javascript
// vitest.workspace.js
export default ['packages/*'];
新方式(Vitest 3.0):
javascript
// vitest.config.js
export default defineConfig({
  test: {
    workspace: [
      {
        test: {
          name: '单元测试',
          include: ['tests/unit/**/*.test.js']
        }
      },
      {
        test: {
          name: '集成测试',
          include: ['tests/integration/**/*.test.js']
        }
      }
    ]
  }
});

6. Enhanced Browser Testing

6. 增强型浏览器测试

Improved browser mode with better performance and caching.
Multiple Browser Instances:
javascript
export default defineConfig({
  test: {
    browser: {
      enabled: true,
      instances: [
        { browser: 'chromium', name: 'chrome' },
        { browser: 'firefox', name: 'ff' },
        { browser: 'webkit', name: 'safari' }
      ]
    }
  }
});
Benefits:
  • Single Vite server for all browsers
  • Cached file processing
  • Parallel browser execution
  • Reduced startup time
改进的浏览器模式,性能和缓存更优。
多浏览器实例配置:
javascript
export default defineConfig({
  test: {
    browser: {
      enabled: true,
      instances: [
        { browser: 'chromium', name: 'chrome' },
        { browser: 'firefox', name: 'ff' },
        { browser: 'webkit', name: 'safari' }
      ]
    }
  }
});
优势:
  • 所有浏览器共享单个Vite服务器
  • 缓存文件处理
  • 浏览器并行执行
  • 缩短启动时间

7. Improved Coverage

7. 改进的覆盖率统计

Automatic exclusion of test files from coverage reports.
Automatic Exclusions (Vitest 3.0):
javascript
export default defineConfig({
  test: {
    coverage: {
      provider: 'v8',
      // Test files automatically excluded
      // No need to manually exclude *.test.js
      exclude: [
        // Only need to specify custom exclusions
        '**/node_modules/**',
        '**/dist/**'
      ]
    }
  }
});
自动将测试文件排除在覆盖率报告之外。
自动排除(Vitest 3.0):
javascript
export default defineConfig({
  test: {
    coverage: {
      provider: 'v8',
      // 测试文件自动被排除
      // 无需手动排除*.test.js
      exclude: [
        // 仅需指定自定义排除项
        '**/node_modules/**',
        '**/dist/**'
      ]
    }
  }
});

8. Enhanced Mocking

8. 增强型Mock功能

New spy reuse and powerful matchers.
Spy Reuse:
javascript
const spy = vi.fn();

// Vitest 3.0: Reuse spy on already mocked method
vi.spyOn(obj, 'method').mockImplementation(spy);
vi.spyOn(obj, 'method'); // Reuses existing spy
New Matchers:
javascript
// toHaveBeenCalledExactlyOnceWith
expect(mockFn).toHaveBeenCalledExactlyOnceWith(arg1, arg2);

// Ensures called exactly once with exact arguments
// Fails if called 0 times, 2+ times, or with different args
新增Spy复用和强大的匹配器。
Spy复用:
javascript
const spy = vi.fn();

// Vitest 3.0:在已被Mock的方法上复用Spy
vi.spyOn(obj, 'method').mockImplementation(spy);
vi.spyOn(obj, 'method'); // 复用已有的Spy
新增匹配器:
javascript
// toHaveBeenCalledExactlyOnceWith
expect(mockFn).toHaveBeenCalledExactlyOnceWith(arg1, arg2);

// 确保函数被精确调用一次,且参数完全匹配
// 如果调用0次、2次及以上,或参数不匹配则失败

9. Project Exclusion Patterns

9. 项目排除模式

Exclude specific projects using negative patterns.
CLI Usage:
bash
undefined
使用负模式排除特定项目。
CLI使用示例:
bash
undefined

Run all except integration tests

运行除集成测试外的所有测试

vitest run --project=!integration
vitest run --project=!integration

Run all except multiple projects

排除多个项目

vitest run --project=!integration --project=!e2e
vitest run --project=!integration --project=!e2e

Combine inclusion and exclusion

组合包含和排除规则

vitest run --project=unit --project=!slow
undefined
vitest run --project=unit --project=!slow
undefined

10. UI Improvements

10. UI改进

Significantly enhanced test UI with better debugging and navigation.
New UI Features:
  • Run individual tests from UI
  • Automatic scroll to failed tests
  • Toggleable node_modules visibility
  • Improved filtering and search
  • Better test management controls
  • Module graph visualization
Launch UI:
bash
vitest --ui
测试UI大幅增强,调试和导航体验更好。
新UI功能:
  • 从UI中运行单个测试
  • 自动滚动到失败的测试
  • 可切换的node_modules可见性
  • 改进的筛选和搜索
  • 更完善的测试管理控件
  • 模块关系图可视化
启动UI:
bash
vitest --ui

Best Practices for Vitest 3.x

Vitest 3.x 最佳实践

1. Use Annotation API for Complex Tests

1. 为复杂测试使用注解API

javascript
test('complex payment flow', async ({ task }) => {
  task.meta.annotation = {
    message: 'Tests Stripe webhook integration',
    attachments: [
      { name: 'webhook-payload', content: JSON.stringify(payload) },
      { name: 'ticket', content: 'https://jira.company.com/TICKET-123' }
    ]
  };

  // Test implementation
});
javascript
test('复杂支付流程', async ({ task }) => {
  task.meta.annotation = {
    message: '测试Stripe webhook集成',
    attachments: [
      { name: 'webhook负载', content: JSON.stringify(payload) },
      { name: '工单', content: 'https://jira.company.com/TICKET-123' }
    ]
  };

  // 测试实现
});

2. Leverage Line Filtering in Development

2. 在开发中使用行号过滤

bash
undefined
bash
undefined

Quick iteration on single test

快速迭代单个测试

vitest run src/auth.test.js:145 --watch
undefined
vitest run src/auth.test.js:145 --watch
undefined

3. Organize with Workspace Projects

3. 使用工作区项目组织测试

javascript
export default defineConfig({
  test: {
    workspace: [
      {
        test: {
          name: 'unit-fast',
          include: ['tests/unit/**/*.test.js'],
          environment: 'node'
        }
      },
      {
        test: {
          name: 'unit-dom',
          include: ['tests/unit/**/*.dom.test.js'],
          environment: 'happy-dom'
        }
      },
      {
        test: {
          name: 'integration',
          include: ['tests/integration/**/*.test.js'],
          setupFiles: ['tests/setup.js']
        }
      }
    ]
  }
});
javascript
export default defineConfig({
  test: {
    workspace: [
      {
        test: {
          name: '快速单元测试',
          include: ['tests/unit/**/*.test.js'],
          environment: 'node'
        }
      },
      {
        test: {
          name: 'DOM单元测试',
          include: ['tests/unit/**/*.dom.test.js'],
          environment: 'happy-dom'
        }
      },
      {
        test: {
          name: '集成测试',
          include: ['tests/integration/**/*.test.js'],
          setupFiles: ['tests/setup.js']
        }
      }
    ]
  }
});

4. Use toHaveBeenCalledExactlyOnceWith for Strict Testing

4. 使用toHaveBeenCalledExactlyOnceWith进行严格测试

javascript
test('should call API exactly once with correct params', () => {
  const apiSpy = vi.spyOn(api, 'fetchUser');

  renderComponent({ userId: 123 });

  // Strict assertion - fails if called 0, 2+ times or wrong args
  expect(apiSpy).toHaveBeenCalledExactlyOnceWith(123);
});
javascript
test('应精确调用API一次且参数正确', () => {
  const apiSpy = vi.spyOn(api, 'fetchUser');

  renderComponent({ userId: 123 });

  // 严格断言 - 如果调用0次、2次及以上,或参数不匹配则失败
  expect(apiSpy).toHaveBeenCalledExactlyOnceWith(123);
});

5. Optimize Watch Mode for Large Projects

5. 为大型项目优化监听模式

javascript
export default defineConfig({
  test: {
    watch: true,
    watchExclude: [
      '**/node_modules/**',
      '**/dist/**',
      '**/.git/**',
      '**/coverage/**'
    ],
    // Run only related tests
    changed: true,
    // Faster reruns
    isolate: false // Use with caution
  }
});
javascript
export default defineConfig({
  test: {
    watch: true,
    watchExclude: [
      '**/node_modules/**',
      '**/dist/**',
      '**/.git/**',
      '**/coverage/**'
    ],
    // 仅运行相关测试
    changed: true,
    // 更快的重运行速度
    isolate: false // 谨慎使用
  }
});

6. Custom Reporters for CI/CD

6. 为CI/CD创建自定义报告器

javascript
// reporters/junit-plus.js
export default class JUnitPlusReporter {
  onFinished(files, errors) {
    const results = files.map(file => ({
      name: file.name,
      tests: file.tasks.length,
      failures: file.tasks.filter(t => t.result?.state === 'fail').length,
      // Add annotations from tests
      annotations: file.tasks
        .map(t => t.meta?.annotation)
        .filter(Boolean)
    }));

    // Export to CI system
    exportToCI(results);
  }
}
javascript
// vitest.config.js
export default defineConfig({
  test: {
    reporters: ['default', './reporters/junit-plus.js']
  }
});
javascript
// reporters/junit-plus.js
export default class JUnitPlusReporter {
  onFinished(files, errors) {
    const results = files.map(file => ({
      name: file.name,
      tests: file.tasks.length,
      failures: file.tasks.filter(t => t.result?.state === 'fail').length,
      // 从测试中添加注解
      annotations: file.tasks
        .map(t => t.meta?.annotation)
        .filter(Boolean)
    }));

    // 导出到CI系统
    exportToCI(results);
  }
}
javascript
// vitest.config.js
export default defineConfig({
  test: {
    reporters: ['default', './reporters/junit-plus.js']
  }
});

Migration from Vitest 2.x to 3.x

从Vitest 2.x迁移到3.x

Breaking Changes

破坏性变更

  1. Workspace Configuration:
    • Move workspace projects into main config
    • Update project references
  2. Reporter API:
    • Update custom reporters to new lifecycle
    • Check reporter method signatures
  3. Browser Mode:
    • Update provider syntax if using browser mode
    • Review browser configuration
  1. 工作区配置:
    • 将工作区项目移到主配置文件中
    • 更新项目引用
  2. 报告器API:
    • 更新自定义报告器以适配新的生命周期
    • 检查报告器方法签名
  3. 浏览器模式:
    • 如果使用浏览器模式,更新provider语法
    • 检查浏览器配置

Migration Steps

迁移步骤

bash
undefined
bash
undefined

Update Vitest

更新Vitest

npm install -D vitest@^3.0.0
npm install -D vitest@^3.0.0

Update related packages

更新相关包

npm install -D @vitest/ui@^3.0.0 npm install -D @vitest/coverage-v8@^3.0.0
npm install -D @vitest/ui@^3.0.0 npm install -D @vitest/coverage-v8@^3.0.0

Run tests to check for issues

运行测试检查问题

npm test
npm test

Update configs based on deprecation warnings

根据弃用警告更新配置

undefined
undefined

Performance Optimization Tips

性能优化技巧

1. Use Workspace Projects for Isolation

1. 使用工作区项目实现隔离

javascript
// Separate fast unit tests from slower integration tests
workspace: [
  {
    test: {
      name: 'unit',
      include: ['tests/unit/**'],
      environment: 'node' // Fastest
    }
  },
  {
    test: {
      name: 'integration',
      include: ['tests/integration/**'],
      environment: 'happy-dom',
      setupFiles: ['tests/setup.js']
    }
  }
]
javascript
// 将快速单元测试与较慢的集成测试分开
workspace: [
  {
    test: {
      name: '单元测试',
      include: ['tests/unit/**'],
      environment: 'node' // 最快
    }
  },
  {
    test: {
      name: '集成测试',
      include: ['tests/integration/**'],
      environment: 'happy-dom',
      setupFiles: ['tests/setup.js']
    }
  }
]

2. Parallelize Test Execution

2. 并行化测试执行

bash
undefined
bash
undefined

Run projects in parallel

并行运行多个项目

vitest run --project=unit --project=integration
vitest run --project=unit --project=integration

Exclude slow tests during development

开发期间排除慢测试

vitest run --project=!e2e --project=!slow
undefined
vitest run --project=!e2e --project=!slow
undefined

3. Use Line Filtering for TDD

3. 为TDD使用行号过滤

bash
undefined
bash
undefined

Rapid iteration on single test

快速迭代单个测试

vitest run src/feature.test.js:42 --watch
undefined
vitest run src/feature.test.js:42 --watch
undefined

4. Optimize Browser Testing

4. 优化浏览器测试

javascript
export default defineConfig({
  test: {
    browser: {
      enabled: true,
      // Reuse context for speed (less isolation)
      isolate: false,
      // Single instance for development
      instances: [{ browser: 'chromium' }]
    }
  }
});
javascript
export default defineConfig({
  test: {
    browser: {
      enabled: true,
      // 复用上下文以提升速度(隔离性降低)
      isolate: false,
      // 开发时仅使用单个实例
      instances: [{ browser: 'chromium' }]
    }
  }
});

Common Patterns

常见模式

Test Annotation for Debugging

用于调试的测试注解

javascript
test('payment processing', async ({ task }) => {
  const startTime = Date.now();

  try {
    const result = await processPayment(data);

    task.meta.annotation = {
      message: `Completed in ${Date.now() - startTime}ms`,
      attachments: [
        { name: 'result', content: JSON.stringify(result) }
      ]
    };

    expect(result.success).toBe(true);
  } catch (error) {
    task.meta.annotation = {
      message: 'Payment processing failed',
      attachments: [
        { name: 'error', content: error.message },
        { name: 'payload', content: JSON.stringify(data) }
      ]
    };
    throw error;
  }
});
javascript
test('支付处理', async ({ task }) => {
  const startTime = Date.now();

  try {
    const result = await processPayment(data);

    task.meta.annotation = {
      message: `处理完成,耗时${Date.now() - startTime}ms`,
      attachments: [
        { name: '结果', content: JSON.stringify(result) }
      ]
    };

    expect(result.success).toBe(true);
  } catch (error) {
    task.meta.annotation = {
      message: '支付处理失败',
      attachments: [
        { name: '错误信息', content: error.message },
        { name: '请求负载', content: JSON.stringify(data) }
      ]
    };
    throw error;
  }
});

Multi-Project Testing Strategy

多项目测试策略

javascript
export default defineConfig({
  test: {
    workspace: [
      // Fast feedback loop
      {
        test: {
          name: 'unit-critical',
          include: ['tests/unit/critical/**'],
          environment: 'node'
        }
      },
      // Standard tests
      {
        test: {
          name: 'unit-standard',
          include: ['tests/unit/**'],
          exclude: ['tests/unit/critical/**'],
          environment: 'happy-dom'
        }
      },
      // Slow integration tests
      {
        test: {
          name: 'integration',
          include: ['tests/integration/**'],
          testTimeout: 30000
        }
      }
    ]
  }
});
javascript
export default defineConfig({
  test: {
    workspace: [
      // 快速反馈循环
      {
        test: {
          name: '核心单元测试',
          include: ['tests/unit/critical/**'],
          environment: 'node'
        }
      },
      // 标准测试
      {
        test: {
          name: '标准单元测试',
          include: ['tests/unit/**'],
          exclude: ['tests/unit/critical/**'],
          environment: 'happy-dom'
        }
      },
      // 慢集成测试
      {
        test: {
          name: '集成测试',
          include: ['tests/integration/**'],
          testTimeout: 30000
        }
      }
    ]
  }
});

Resources

资源