测试覆盖率
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.
// 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
配置
¥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.
// 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 |
cypress | 用 CYPRESS_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.json
或 nyc.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
):
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.
// 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
-
组件测试 提供有关用户行为模拟
¥Component tests for user behavior simulation
-
视觉测试 用于外观
¥Visual tests for appearance
-
可访问性测试 用于可访问性
¥Accessibility tests for accessibility
-
快照测试 提供有关渲染错误和警告
¥Snapshot tests for rendering errors and warnings
-
测试运行器 用于自动化测试执行
¥Test runner to automate test execution
-
用于测量代码覆盖率的测试覆盖率
¥Test coverage for measuring code coverage
-
端到端测试 提供有关模拟真实用户场景
¥End-to-end tests for simulating real user scenarios
-
单元测试 用于功能性
¥Unit tests for functionality