Skip to content
Vitest 3
Main Navigation 指南 & API配置浏览器模式高级 API
3.2.0
2.1.9
1.6.1
0.34.6

简体中文

English
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

简体中文

English
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

主题

Sidebar Navigation

简介

为什么选择 Vitest

快速入门

特性

配置 Vitest

API

测试 API 参考

模拟函数

Vi

expect

expectTypeOf

assert

assertType

指南

命令行界面

测试过滤

测试项目

报告器

覆盖率

快照

模拟

并行

类型测试

Vitest UI

源内测试

测试上下文

测试注解

测试环境

扩展匹配器

IDE 集成

调试

常见错误

迁移指南

迁移到 Vitest 3.0

从 Jest 迁移

性能

分析测试性能

性能优化

浏览器模式

高级 API

与其他测试运行器的比较

页面导航

覆盖率 ​

Vitest 通过 v8 支持原生代码覆盖,并通过 istanbul 支持代码插桩覆盖。

覆盖率提供者 ​

v8 和 istanbul 的支持都是可选的。默认情况下,Vitest 会使用 v8。

你可以通过将 test.coverage.provider 设置为 v8 或 istanbul 来选择覆盖率工具:

ts
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    coverage: {
      provider: 'istanbul', // 或 'v8'
    },
  },
});

当你启动 Vitest 进程时,它会自动提示并引导你安装相应的支持包。

或者,你也可以选择手动安装它们:

bash
npm i -D @vitest/coverage-v8
bash
npm i -D @vitest/coverage-istanbul

V8 提供者 ​

INFO

以下对 V8 覆盖率的描述仅适用于 Vitest,不适用于其他测试运行器。 自 v3.2.0 起,Vitest 已对 V8 覆盖率采用 基于 AST 的覆盖率重映射,这会生成与 Istanbul 相同的覆盖率报告。

这使得用户能够兼顾 V8 覆盖率的速度和 Istanbul 覆盖率的准确性。

默认情况下,Vitest 使用 'v8' 覆盖率提供者。 此提供者需要基于 V8 引擎 的 JavaScript 运行时,例如 NodeJS、Deno 或任何基于 Chromium 的浏览器(如 Google Chrome)。

覆盖率收集是在运行时进行的,通过使用 node:inspector 指示 V8,并在浏览器中使用 Chrome DevTools Protocol 来实现。用户的源文件无需任何预插桩步骤即可直接执行。

  • ✅ 推荐使用的选项
  • ✅ 无需预转译步骤。测试文件可以原封不动地执行。
  • ✅ 执行速度比 Istanbul 快。
  • ✅ 内存占用比 Istanbul 低。
  • ✅ 覆盖率报告的准确性与 Istanbul 相当(自 Vitest v3.2.0 起)。
  • ⚠️ 在某些情况下,例如加载大量不同模块时,可能会比 Istanbul 慢。V8 不支持将覆盖率收集限制到特定模块。
  • ⚠️ V8 引擎存在一些次要限制。请参阅 ast-v8-to-istanbl | 限制。
  • ❌ 不适用于不使用 V8 的环境(例如 Firefox 或 Bun),也不适用于不通过分析器暴露 V8 覆盖率的环境(例如 Cloudflare Workers)。

Istanbul 提供者 ​

Istanbul 代码覆盖率工具 自 2012 年以来一直存在,并经过了充分的实战验证。 此提供者适用于任何 JavaScript 运行时,因为覆盖率跟踪是通过对用户源文件进行插桩实现的。

实际上,对源文件进行插桩意味着在用户文件中注入额外的 JavaScript 代码:

js
// 分支和函数覆盖计数器的简化示例
const coverage = { 
  branches: { 1: [0, 0] }, 
  functions: { 1: 0 }, 
} 

export function getUsername(id) {
  // 此函数被调用时,函数覆盖率增加
  coverage.functions['1']++; 

  if (id == null) {
    // 此分支被执行时,分支覆盖率增加
    coverage.branches['1'][0]++; 

    throw new Error('User ID is required');
  }
  // 当 if 语句条件不满足时,隐式 else 覆盖率会增加
  coverage.branches['1'][1]++; 

  return database.getUser(id);
}

globalThis.__VITEST_COVERAGE__ ||= {}; 
globalThis.__VITEST_COVERAGE__[filename] = coverage; 
  • ✅ 适用于任何 JavaScript 运行时
  • ✅ 广泛使用并经过 13 年多的实战检验。
  • ✅ 在某些情况下,可能会比 V8 快。覆盖率插桩可以限制到特定文件,而 V8 则会对所有模块进行插桩。
  • ❌ 需要预先进行插桩步骤
  • ❌ 由于插桩开销,执行速度会比 V8 慢
  • ❌ 插桩会导致文件大小增加
  • ❌ 内存占用比 V8 高

覆盖率设置 ​

TIP

建议始终在配置文件中定义 coverage.include 选项。 这有助于 Vitest 减少 coverage.all 所包含的文件数量。

要启用覆盖率测试,你可以在 CLI 中传递 --coverage 标志。 默认情况下,将使用 ['text', 'html', 'clover', 'json'] 这些报告器。

json
{
  "scripts": {
    "test": "vitest",
    "coverage": "vitest run --coverage"
  }
}

要进行配置,请在你的配置文件中设置 test.coverage 选项:

ts
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    coverage: {
      reporter: ['text', 'json', 'html'],
    },
  },
});

自定义覆盖率报告器 ​

你可以通过在 test.coverage.reporter 中指定包名或绝对路径来使用自定义覆盖率报告器:

ts
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    coverage: {
      reporter: [
        // 使用 NPM 包名指定报告器
        ['@vitest/custom-coverage-reporter', { someOption: true }],

        // 使用本地路径指定报告器
        '/absolute/path/to/custom-reporter.cjs',
      ],
    },
  },
});

自定义报告器由 Istanbul 加载,并且必须实现其报告器接口。请参阅 内置报告器的实现 以供参考。

js
const { ReportBase } = require('istanbul-lib-report');

module.exports = class CustomReporter extends ReportBase {
  constructor(opts) {
    super();

    // 配置中传递的选项可在此处使用
    this.file = opts.file;
  }

  onStart(root, context) {
    this.contentWriter = context.writer.writeFile(this.file);
    this.contentWriter.println('自定义覆盖率报告开始');
  }

  onEnd() {
    this.contentWriter.println('自定义覆盖率报告结束');
    this.contentWriter.close();
  }
};

自定义覆盖率提供者 ​

也可以通过将 test.coverage.provider 设置为 'custom' 来提供自定义覆盖率提供者:

ts
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    coverage: {
      provider: 'custom',
      customProviderModule: 'my-custom-coverage-provider',
    },
  },
});

自定义提供者需要一个 customProviderModule 选项,该选项指定了加载 CoverageProviderModule 的模块名称或路径。它必须默认导出一个实现 CoverageProviderModule 接口的对象:

ts
import type {
  CoverageProvider,
  CoverageProviderModule,
  ResolvedCoverageOptions,
  Vitest,
} from 'vitest';

const CustomCoverageProviderModule: CoverageProviderModule = {
  getProvider(): CoverageProvider {
    return new CustomCoverageProvider();
  },

  // 实现 CoverageProviderModule 的其他方法...
};

class CustomCoverageProvider implements CoverageProvider {
  name = 'custom-coverage-provider';
  options!: ResolvedCoverageOptions;

  initialize(ctx: Vitest) {
    this.options = ctx.config.coverage;
  }

  // 实现 CoverageProvider 的其他方法...
}

export default CustomCoverageProviderModule;

请参阅类型定义了解更多详细信息。

更改默认覆盖率文件夹位置 ​

生成覆盖率报告时,会在项目根目录中创建一个 coverage 文件夹。如果你想将其移动到其他目录,请在 vitest.config.js 文件中使用 test.coverage.reportsDirectory 属性。

js
import { defineConfig } from 'vite';

export default defineConfig({
  test: {
    coverage: {
      reportsDirectory: './tests/unit/coverage',
    },
  },
});

忽略代码 ​

两种覆盖率提供者都有各自忽略覆盖率报告中代码的方式:

  • v8
  • ìstanbul
  • v8 与 experimentalAstAwareRemapping: true 请参阅 ast-v8-to-istanbul | 忽略代码

使用 TypeScript 时,源代码会通过 esbuild 进行转译,这会移除源代码中的所有注释 (esbuild#516)。 被视为 合法注释 的注释会被保留。

你可以在忽略提示中加入 @preserve 关键字。 请注意,这些忽略提示现在也可能会被包含在最终的生产构建中。

diff
-/* istanbul ignore if */
+/* istanbul ignore if -- @preserve */
if (condition) {

-/* v8 ignore if */
+/* v8 ignore if -- @preserve */
if (condition) {

其他选项 ​

查看所有可配置的覆盖率选项,请参阅 覆盖率配置参考。

覆盖率性能 ​

如果你的项目代码覆盖率生成速度较慢,请参阅 分析测试性能 | 代码覆盖率。

Vitest UI ​

你可以在 Vitest UI 中查看覆盖率报告。

当明确启用覆盖率且存在 HTML 覆盖率报告器时,Vitest UI 将启用覆盖率报告功能,否则该功能将不可用:

  • 在你的配置文件中将 coverage.enabled 设置为 true,或使用 --coverage.enabled=true 标志运行 Vitest
  • 将 html 添加到 coverage.reporter 列表中;你还可以启用 subdir 选项,将覆盖率报告放置在子目录中。
Vitest UI 中 html 覆盖率激活Vitest UI 中 html 覆盖率激活Vitest UI 中的 html 覆盖率Vitest UI 中的 html 覆盖率
Pager
上一页报告器
下一页快照

基于 MIT 许可证 发布。

版权所有 (c) 2021-Present Vitest Team

https://vitest.dev/guide/coverage

基于 MIT 许可证 发布。

版权所有 (c) 2021-Present Vitest Team