mcpField
V
vitest-3-features

vitest-3-features

github.com/josiahsiegel测试与质量59165 次安装19 周前更新
代码仓库

关于 vitest-3-features

面向 Vitest 3.x 开发者的参考技能,涵盖测试功能、配置及从 Vitest 2.x 迁移的要点,并介绍定向运行、浏览器测试、报告和项目组织。

主要功能

  1. 01测试注释与附件
  2. 02按行号选择测试
  3. 03监视模式与报告改进
  4. 04工作区项目配置
  5. 05浏览器测试与覆盖率指南
  6. 06模拟与匹配器更新

适用场景

  1. 01开发时运行单个测试
  2. 02组织单元与集成测试项目
  3. 03向测试报告添加元数据
  4. 04将项目从 Vitest 2.x 迁移

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/josiahsiegel/claude-plugin-marketplace --skill vitest-3-features

安装后在 Claude Code 中输入/vitest-3-features确认已加载。

详细介绍

🚨 重要指南

Windows 文件路径要求

必须:在 Windows 上始终使用反斜杠表示文件路径

在 Windows 上使用 Edit 或 Write 工具时,必须在文件路径中使用反斜杠(\),而不是正斜杠(/)。

示例:

  • ❌ 错误:D:/repos/project/file.tsx
  • ✅ 正确:D:\repos\project\file.tsx

适用于:

  • Edit 工具的 file_path 参数
  • Write 工具的 file_path 参数
  • Windows 系统上的所有文件操作
文档指南

除非用户明确要求,否则绝不要创建新的文档文件。

  • 优先级:更新现有的 README.md 文件,而不是创建新文档
  • 仓库整洁度:保持仓库根目录整洁——除非用户另有要求,否则只保留 README.md
  • 风格:文档应简洁、直接、专业,避免使用 AI 生成式语气
  • 用户偏好:只有用户明确要求编写文档时,才创建其他 .md 文件

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

概述

Vitest 3.0 于 2025 年 1 月发布,在报告、浏览器测试、监视模式和开发者体验方面进行了重大改进。本指南全面介绍 Vitest 3.x 的功能和现代测试模式。

Vitest 3.0+ 的主要功能

1. 注解 API(Vitest 3.2+)

注解 API 允许你向任何测试添加自定义元数据、消息和附件,并在 UI、HTML、JUnit、TAP 和 GitHub Actions 报告器中查看。

用法:

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();
});

使用场景:

  • 记录复杂的测试场景
  • 附加调试信息
  • 链接到外部资源(工单、文档)
  • 添加性能指标
  • 跟踪用于报告的测试元数据
2. 按行号筛选

通过文件中的行号运行特定测试,以便从 IDE 精确执行测试。

CLI 用法:

# Run test at specific line
vitest run tests/user.test.js:42

# Run multiple tests by line
vitest run tests/user.test.js:42 tests/user.test.js:67

# Works with ranges
vitest run tests/user.test.js:42-67

IDE 集成:

  • VS Code:点击行号栏
  • JetBrains IDE:从上下文菜单运行
  • 支持“运行光标所在处的测试”功能
3. 增强的监视模式

监视模式更加智能、响应更快,变更检测也得到改进。

功能:

  • 更准确地检测变更
  • 仅重新运行受影响的测试
  • 更快的重建速度
  • 在 Windows 上更好地监视文件
  • 减少误报

配置:

export default defineConfig({
  test: {
    watch: true,
    watchExclude: ['**/node_modules/**', '**/dist/**'],
    // New in 3.0: More intelligent caching
    cache: {
      dir: '.vitest/cache'
    }
  }
});
4. 改进的测试报告

全面改进了测试运行报告,减少闪烁并让输出更清晰。

报告器 API 变更:

// 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
  }
}

优势:

  • 测试运行期间终端闪烁更少
  • 测试状态指示更清晰
  • 错误格式更易读
  • 改进进度跟踪
5. 简化工作区配置

无需单独的工作区文件,可直接在配置中定义项目。

旧方式(Vitest 2.x):

// vitest.workspace.js
export default ['packages/*'];

新方式(Vitest 3.0):

// vitest.config.js
export default defineConfig({
  test: {
    workspace: [
      {
        test: {
          name: 'unit',
          include: ['tests/unit/**/*.test.js']
        }
      },
      {
        test: {
          name: 'integration',
          include: ['tests/integration/**/*.test.js']
        }
      }
    ]
  }
});
6. 增强的浏览器测试

改进了浏览器模式的性能和缓存机制。

多个浏览器实例:

export default defineConfig({
  test: {
    browser: {
      enabled: true,
      instances: [
        { browser: 'chromium', name: 'chrome' },
        { browser: 'firefox', name: 'ff' },
        { browser: 'webkit', name: 'safari' }
      ]
    }
  }
});

优势:

  • 所有浏览器共用一个 Vite 服务
  • 缓存文件处理结果
  • 并行执行浏览器测试
  • 缩短启动时间
7. 改进的覆盖率

自动将测试文件排除在覆盖率报告之外。

自动排除项(Vitest 3.0):

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/**'
      ]
    }
  }
});
8. 增强的模拟功能

新增间谍函数复用和强大的匹配器。

间谍函数复用:

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

新匹配器:

// toHaveBeenCalledExactlyOnceWith
expect(mockFn).toHaveBeenCalledExactlyOnceWith(arg1, arg2);

// Ensures called exactly once with exact arguments
// Fails if called 0 times, 2+ times, or with different args
9. 项目排除模式

使用否定模式排除特定项目。

CLI 用法:

# Run all except integration tests
vitest run --project=!integration

# Run all except multiple projects
vitest run --project=!integration --project=!e2e

# Combine inclusion and exclusion
vitest run --project=unit --project=!slow
10. UI 改进

大幅增强了测试 UI,提供更好的调试和导航体验。

UI 新功能:

  • 在 UI 中运行单个测试
  • 自动滚动到失败的测试
  • 可切换 node_modules 的可见性
  • 改进筛选和搜索
  • 更完善的测试管理控件
  • 模块图可视化

启动 UI:

vitest --ui

Vitest 3.x 最佳实践

1. 使用注解 API 处理复杂测试
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
});
2. 在开发中充分利用按行筛选
# Quick iteration on single test
vitest run src/auth.test.js:145 --watch
3. 使用工作区项目组织测试
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']
        }
      }
    ]
  }
});
4. 使用 toHaveBeenCalledExactlyOnceWith 进行严格测试
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);
});
5. 优化大型项目的监视模式
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
  }
});
6. 为 CI/CD 使用自定义报告器
// 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);
  }
}
// vitest.config.js
export default defineConfig({
  test: {
    reporters: ['default', './reporters/junit-plus.js']
  }
});

从 Vitest 2.x 迁移到 3.x

破坏性变更
  1. 工作区配置:

    • 将工作区项目移至主配置中
    • 更新项目引用
  2. 报告器 API:

    • 将自定义报告器更新为使用新的生命周期
    • 检查报告器方法签名
  3. 浏览器模式:

    • 如果使用浏览器模式,请更新提供程序语法
    • 检查浏览器配置
迁移步骤
# Update Vitest
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

# Run tests to check for issues
npm test

# Update configs based on deprecation warnings

性能优化技巧

1. 使用工作区项目实现隔离
// 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']
    }
  }
]
2. 并行执行测试
# Run projects in parallel
vitest run --project=unit --project=integration

# Exclude slow tests during development
vitest run --project=!e2e --project=!slow
3. 使用行过滤进行 TDD
# Rapid iteration on single test
vitest run src/feature.test.js:42 --watch
4. 优化浏览器测试
export default defineConfig({
  test: {
    browser: {
      enabled: true,
      // Reuse context for speed (less isolation)
      isolate: false,
      // Single instance for development
      instances: [{ browser: 'chromium' }]
    }
  }
});

常见模式

用于调试的测试注释
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;
  }
});
多项目测试策略
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
        }
      }
    ]
  }
});

资源

评论

支持 Markdown