加入直播会议:周四,美国东部时间上午 11 点,Storybook 9 发布及 AMA
文档
Storybook Docs

测试覆盖率

测试覆盖率是一种衡量现有测试是否完全覆盖代码的实践。它标记了代码中哪些条件、逻辑分支、函数和变量被测试到,哪些没有被测试到。

覆盖率测试根据一组行业公认的最佳实践来检查已插桩的代码。它们作为质量保证的最后一道防线,旨在提高测试套件的质量。

每个项目的覆盖率报告看起来都会不同,但需要注意的重要事项是

  1. 整体行/分支覆盖率,这作为一种高层级的健康检查。
  2. 未覆盖到的特定行/分支,这些是潜在的测试盲点。

使用Vitest 插件运行组件测试时,它可以生成覆盖率报告。结果会汇总在测试小部件中,显示您已测试的故事所覆盖的语句百分比。

Test widget with coverage summary

如果您的项目无法使用 Vitest 插件,仍然可以使用测试运行器生成代码覆盖率。请按照测试运行器文档中的说明在项目中设置带有代码覆盖率的测试运行器。

设置

覆盖率包含在Vitest 插件中,启用后,在运行项目组件测试时会计算覆盖率。要启用覆盖率,请在测试小部件中勾选覆盖率复选框。

Screenshot of testing widget, expanded, showing coverage toggle

在计算覆盖率之前,您可能需要安装与您的覆盖率提供者对应的支持包

# For v8
npm install --save-dev @vitest/coverage-v8
 
# For istanbul
npm install --save-dev @vitest/coverage-istanbul

用法

由于覆盖率内置于 Vitest 插件中,您可以在任何运行测试的地方使用它。

Storybook UI

在 Storybook UI 中启用覆盖率后,运行测试后将生成并汇总覆盖率报告到测试小部件中。您可以查看已测试故事覆盖的语句百分比,以及覆盖率是否达到水线

此外,完整的覆盖率报告将通过运行中的 Storybook 的 /coverage/index.html 路由提供。

Two browser windows. The frontmost one shows the interactive coverage report generated by the Vitest addon. The background one shows the Storybook sidebar with the coverage summary visible in the testing widget.

报告是交互式的。您可以点击进入一个组件,查看其源代码,并了解代码的哪些部分被测试覆盖或未覆盖

Interactive coverage report generated by the Vitest addon, showing the Calendar component's reported source

重要的是要理解,Storybook UI 中报告的覆盖率有三个重要的限制

  1. 覆盖率是使用您编写的故事计算的,而不是整个代码库。换句话说,它不包含任何其他 Vitest 测试。
  2. 覆盖率只能针对项目中的所有故事进行计算,不能针对单个故事或故事组进行计算。
  3. 在观察模式激活时,不会计算覆盖率。启用覆盖率时,启用观察模式将禁用覆盖率。

命令行 (CLI)

与 Storybook 测试的其余部分一样,覆盖率构建在 Vitest 之上。这意味着您可以使用Vitest 命令行工具生成覆盖率报告。

假设您使用以下软件包脚本运行测试

package.json
{
  "scripts": {
    "test-storybook": "vitest --project=storybook"
  }
}

然后您可以使用以下命令生成覆盖率报告

npm run test-storybook -- --coverage

Generated coverage report in terminal

覆盖率报告将保存到项目中的配置的覆盖率报告目录(默认为./coverage)。

上面的命令只会计算您编写的故事的覆盖率,而不是整个代码库。

由于覆盖率在计算项目中的所有测试时最准确,您也可以使用以下命令为项目中的所有测试运行覆盖率计算

npx vitest --coverage

编辑器扩展

覆盖率也通过 Vitest 的IDE 集成提供。您可以直接在编辑器中计算和显示覆盖率结果。

Screenshot of test coverage in VSCode

请注意,此覆盖率将包括项目中的所有测试,而不仅仅是您编写的故事。

持续集成 (CI)

要在持续集成流水线中生成覆盖率报告,您可以使用命令行工具

例如,以下是一个简化的 GitHub Actions 工作流程,它运行测试并生成覆盖率报告

.github/workflows/test-storybook.yml
name: Storybook Tests
on: push
jobs:
  test:
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20.x'
      - name: Install dependencies
        run: yarn
        # 👇 This will run all Vitest tests, including Storybook tests
      - name: Run tests
        run: yarn test --coverage

为什么我们要运行所有测试(yarn test),而不仅仅是 Storybook 测试(yarn test-storybook)?因为覆盖率报告在计算项目中的所有测试时最准确,而不仅仅是您编写的故事。

查看Storybook 特定的覆盖率可能有所帮助,但在 CI 输出中,您需要看到项目的全面覆盖率。

有关持续集成中测试的更多信息,请参阅专门指南

配置

覆盖率提供者

您可以通过在 Vitest 配置中设置 coverage.provider 选项,选择用于计算覆盖率的提供者,可以是 v8(默认)或 Istanbul

vitest.config.ts
import { defineConfig } from 'vitest/config';
 
export default defineConfig({
  // ...
  test: {
    // ...
    coverage: {
      // ...
      provider: 'istanbul', // 'v8' is the default
    },
  },
});

水线

两种覆盖率提供者都支持水线,这是覆盖率的阈值。低水线是通过测试所需的最低覆盖率,高水线是被认为良好的最低覆盖率。介于低水线和高水线之间的覆盖率百分比将被认为是可接受的,但不是理想的。

在测试小部件中,覆盖率汇总将显示您的已测试故事覆盖的语句百分比,以及覆盖率是否达到水线。低于低水线时,图标将显示为红色;介于低水线和高水线之间时,显示为橙色;高于高水线时,显示为绿色。

要配置水线,您可以调整 Vitest 配置

vitest.config.ts
import { defineConfig } from 'vitest/config';
 
export default defineConfig({
  // ...
  test: {
    // ...
    coverage: {
      // ...
      watermarks: {
        // These are the default values
        statements: [50, 80],
      },
    },
  },
});

额外配置

您可以在Vitest 文档中找到更多覆盖率配置选项。

在 Storybook UI 中计算覆盖率时,以下选项始终被忽略

  • enabled
  • clean
  • cleanOnRerun
  • reportOnFailure
  • reporter
  • reportsDirectory

更多测试资源