Docs
Storybook Docs

测试覆盖率

Watch a video tutorial

测试覆盖率是测量现有测试是否完全覆盖代码的做法。这意味着显示当前未测试的区域,例如:条件、逻辑分支、函数和变量。

¥Test coverage is the practice of measuring whether existing tests fully cover your code. That means surfacing areas which aren't currently being tested, such as: conditions, logic branches, functions and variables.

覆盖率测试根据一组行业认可的最佳实践检查已检测的代码。它们充当 QA 的最后一行,以提高测试套件的质量。

¥Coverage tests examine the instrumented code against a set of industry-accepted best practices. They act as the last line of QA to improve the quality of your test suite.

使用覆盖插件进行代码检测

¥Code instrumentation with the coverage addon

Storybook 提供官方 测试覆盖率插件。由 伊斯坦布尔 提供支持,可对 JavaScript 生态系统中最常用的框架和构建器进行开箱即用的代码检测。

¥Storybook provides an official test coverage addon. Powered by Istanbul, which allows out-of-the-box code instrumentation for the most commonly used frameworks and builders in the JavaScript ecosystem.

设置覆盖插件

¥Set up the coverage addon

覆盖率插件经过精心设计,可与现代测试工具(例如 Playwright)配合使用,可自动检测你的代码并生成代码覆盖率数据。为了获得最佳体验,我们建议将 测试运行器 与覆盖插件一起使用来运行测试。

¥Engineered to work alongside modern testing tools (e.g., Playwright), the coverage addon automatically instruments your code and generates code coverage data. For an optimal experience, we recommend using the test runner alongside the coverage addon to run your tests.

运行以下命令来安装插件。

¥Run the following command to install the addon.

npm install @storybook/addon-coverage --save-dev

更新你的 Storybook 配置(在 .storybook/main.js|ts 中)以包含覆盖插件。

¥Update your Storybook configuration (in .storybook/main.js|ts) to include the coverage addon.

.storybook/main.ts
// Replace your-framework with the framework and builder you are using (e.g., react-webpack5, vue3-webpack5)
import type { StorybookConfig } from '@storybook/your-framework';
 
const config: StorybookConfig = {
  stories: [],
  addons: [
    // Other Storybook addons
    '@storybook/addon-coverage', //👈 Registers the addon
  ],
};
 
export default config;

使用以下方式启动 Storybook:

¥Start your Storybook with:

npm run storybook

最后,打开一个新的终端窗口并运行测试运行器:

¥Finally, open a new terminal window and run the test-runner with:

npm run test-storybook -- --coverage

Coverage test output

配置

¥Configure

默认情况下,@storybook/addon-coverage 为 Storybook 提供零配置支持,并通过 istanbul-lib-instrument(用于 Webpack)或 vite-plugin-istanbul(用于 Vite)为你的代码提供支持。但是,你可以扩展 Storybook 配置文件(即 .storybook/main.js|ts)并为插件提供其他选项。下面列出了按构建器划分的可用选项及其使用方法示例。

¥By default, the @storybook/addon-coverage offers zero-config support for Storybook and instruments your code via istanbul-lib-instrument for Webpack, or vite-plugin-istanbul for Vite. However, you can extend your Storybook configuration file (i.e., .storybook/main.js|ts) and provide additional options to the addon. Listed below are the available options divided by builder and examples of how to use them.

.storybook/main.ts
// For Vite support add the following import
// import type { AddonOptionsVite } from '@storybook/addon-coverage';
 
import type { AddonOptionsWebpack } from '@storybook/addon-coverage';
 
// Replace your-framework with the framework and builder you are using (e.g., react-webpack5, vue3-webpack5)
import type { StorybookConfig } from '@storybook/your-framework';
 
const coverageConfig: AddonOptionsWebpack = {
  istanbul: {
    include: ['**/stories/**'],
    exclude: ['**/exampleDirectory/**'],
  },
};
 
const config: StorybookConfig = {
  stories: [],
  addons: [
    // Other Storybook addons
    {
      name: '@storybook/addon-coverage',
      options: coverageConfig,
    },
  ],
};
 
export default config;
Vite 选项描述类型
checkProd配置插件以在生产环境中跳过检测
options: { istanbul: { checkProd: true,}}
boolean
cwd配置覆盖率测试的工作目录。
默认为 process.cwd()
options: { istanbul: { cwd: process.cwd(),}}
string
cypressCYPRESS_COVERAGE 替换 VITE_COVERAGE 环境变量。
需要 Cypress 的 代码覆盖率
options: { istanbul: { cypress: true,}}
boolean
exclude使用提供的要从覆盖范围中排除的文件或目录列表覆盖 默认排除列表
Array<String>string
extension使用提供的文件扩展名列表扩展 默认扩展列表 以包含在覆盖范围
options: { istanbul: { extension: ['.js', '.cjs', '.mjs'],}}
Array<String>string
forceBuildInstrument配置插件以在构建模式下添加检测
options: { istanbul: { forceBuildInstrument: true,}}
boolean
include选择要收集覆盖率的文件
options: { istanbul: { include: ['**/stories/**'],}}
Array<String>string
nycrcPath定义现有 nyc 的相对路径 配置文件
options: { istanbul: { nycrcPath: '../nyc.config.js',}}
string
requireEnv通过授予对 env 变量的访问权限来覆盖 VITE_COVERAGE 环境变量的值
options: { istanbul: { requireEnv: true,}}
boolean
Webpack 5 选项描述类型
autoWrap通过将程序代码封装在函数中来提供对顶层返回语句的支持
options: { istanbul: { autoWrap: true,}}
boolean
compact压缩已检测代码的输出。用于调试
options: { istanbul: { compact: false,}}
boolean
coverageVariable定义 Istanbul 将用于存储覆盖率结果的全局变量名称
options: { istanbul: { coverageVariable: '__coverage__',}}
string
cwd配置覆盖率测试的工作目录。
默认为 process.cwd()
options: { istanbul: { cwd: process.cwd(),}}
string
debug在检测过程中启用调试模式以获取其他日志记录信息
options: { istanbul: { debug: true,}}
boolean
esModules启用对 ES 模块语法的支持
options: { istanbul: { esModules: true,}}
boolean
exclude使用提供的要从覆盖范围中排除的文件或目录列表覆盖 默认排除列表
Array<String>string
extension使用提供的文件扩展名列表扩展 默认扩展列表 以包含在覆盖范围
options: { istanbul: { extension: ['.js', '.cjs', '.mjs'],}}
Array<String>string
include选择要收集覆盖率的文件
options: { istanbul: { include: ['**/stories/**'],}}
Array<String>string
nycrcPath定义现有 nyc 的相对路径 配置文件
options: { istanbul: { nycrcPath: '../nyc.config.js',}}
string
preserveComments在已检测的代码中包含注释
options: { istanbul: { preserveComments: true,}}
boolean
produceSourceMap配置 Instanbul 以生成已检测代码的源映射
options: { istanbul: { produceSourceMap: true,}}
boolean
sourceMapUrlCallback定义一个回调函数,在生成源映射时使用文件名和源映射 URL 调用
options: { istanbul: { sourceMapUrlCallback: (filename, url) => {},}}
function

其他覆盖率报告工具怎么样?

¥What about other coverage reporting tools?

开箱即用,代码覆盖率测试可与 Storybook 的测试运行器和 @storybook/addon-coverage 无缝协作。但是,这并不意味着你不能使用其他报告工具(例如 Codecov)。例如,如果你正在使用 LCOV,则可以使用生成的输出(在 coverage/storybook/coverage-storybook.json 中)并创建自己的报告:

¥Out of the box, code coverage tests work seamlessly with Storybook's test-runner and the @storybook/addon-coverage. However, that doesn't mean you can't use additional reporting tools (e.g., Codecov). For instance, if you're working with LCOV, you can use the generated output (in coverage/storybook/coverage-storybook.json) and create your own report with:

npx nyc report --reporter=lcov -t coverage/storybook --report-dir coverage/storybook

故障排除

¥Troubleshooting

在其他框架中运行测试覆盖率

¥Run test coverage in other frameworks

如果你打算在具有特殊文件(如 Vue 3 或 Svelte)的框架中运行覆盖率测试,则需要调整配置并启用所需的文件扩展名。例如,如果你使用的是 Vue,则需要将以下内容添加到 nyc 配置文件(即 .nycrc.jsonnyc.config.js)中:

¥If you intend on running coverage tests in frameworks with special files like Vue 3 or Svelte, you'll need to adjust your configuration and enable the required file extensions. For example, if you're using Vue, you'll need to add the following to your nyc configuration file (i.e., .nycrc.json or nyc.config.js):

.nyc.config.js
export default {
  // Other configuration options
  extension: ['.js', '.cjs', '.mjs', '.ts', '.tsx', '.jsx', '.vue'],
};

覆盖率插件不支持优化构建

¥The coverage addon doesn't support optimized builds

如果你使用 --test 标志生成了针对性能优化的生产版本,并且你正在使用覆盖率插件对你的 Storybook 运行测试,则可能会遇到覆盖率插件不会检测你的代码的情况。这是由于标志的工作方式,因为它会删除对性能有影响的附加组件(例如,Docs覆盖插件)。要解决此问题,你需要调整 Storybook 配置文件(即 .storybook/main.js|ts)并包含 disabledAddons 选项以允许插件以较慢的构建速度为代价运行测试。

¥If you generated a production build optimized for performance with the --test flag, and you're using the coverage addon to run tests against your Storybook, you may run into a situation where the coverage addon doesn't instrument your code. This is due to how the flag works, as it removes addons that have an impact on performance (e.g., Docs, coverage addon). To resolve this issue, you'll need to adjust your Storybook configuration file (i.e., .storybook/main.js|ts) and include the disabledAddons option to allow the addon to run tests at the expense of a slower build.

.storybook/main.ts
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
import type { StorybookConfig } from '@storybook/your-framework';
 
const config: StorybookConfig = {
  framework: '@storybook/your-framework',
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  addons: [
    '@storybook/addon-links',
    '@storybook/addon-essentials',
    '@storybook/addon-interactions',
    '@storybook/addon-coverage',
  ],
  build: {
    test: {
      disabledAddons: ['@storybook/addon-docs', '@storybook/addon-essentials/docs'],
    },
  },
};
 
export default config;

覆盖率插件不支持已检测代码

¥The coverage addon doesn't support instrumented code

由于 覆盖插件 基于 Webpack5 加载器和 Vite 插件进行代码检测,因此不依赖这些库的框架(例如,使用 Webpack 配置的 Angular)将需要额外的配置才能启用代码检测。在这种情况下,你可以参考以下 repository 了解更多信息。

¥As the coverage addon is based on Webpack5 loaders and Vite plugins for code instrumentation, frameworks that don't rely upon these libraries (e.g., Angular configured with Webpack), will require additional configuration to enable code instrumentation. In that case, you can refer to the following repository for more information.

了解其他 UI 测试

¥Learn about other UI tests