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
undefinedRun 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" functionalityvitest 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 spyNew 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
undefinedRun 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
undefinedvitest run --project=unit --project=!slow
undefined10. 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 --uiBest 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
undefinedbash
undefinedQuick iteration on single test
快速迭代单个测试
vitest run src/auth.test.js:145 --watch
undefinedvitest run src/auth.test.js:145 --watch
undefined3. 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
破坏性变更
-
Workspace Configuration:
- Move workspace projects into main config
- Update project references
-
Reporter API:
- Update custom reporters to new lifecycle
- Check reporter method signatures
-
Browser Mode:
- Update provider syntax if using browser mode
- Review browser configuration
-
工作区配置:
- 将工作区项目移到主配置文件中
- 更新项目引用
-
报告器API:
- 更新自定义报告器以适配新的生命周期
- 检查报告器方法签名
-
浏览器模式:
- 如果使用浏览器模式,更新provider语法
- 检查浏览器配置
Migration Steps
迁移步骤
bash
undefinedbash
undefinedUpdate 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
根据弃用警告更新配置
undefinedundefinedPerformance 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
undefinedbash
undefinedRun 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
undefinedvitest run --project=!e2e --project=!slow
undefined3. Use Line Filtering for TDD
3. 为TDD使用行号过滤
bash
undefinedbash
undefinedRapid iteration on single test
快速迭代单个测试
vitest run src/feature.test.js:42 --watch
undefinedvitest run src/feature.test.js:42 --watch
undefined4. 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
}
}
]
}
});