前端项目测试覆盖率检测
2026年1月7日 14:39
背景介绍
什么是测试覆盖率?
测试覆盖率(Test Coverage)是衡量代码被测试用例覆盖程度的指标。它帮助开发者了解:
- 哪些代码已被测试:确保关键功能有测试保护
- 哪些代码未被测试:识别测试盲点,发现潜在风险
- 代码质量趋势:通过覆盖率变化评估代码质量改进情况
测试框架
本文使用 Jest 作为测试框架,配合 ts-jest 支持 TypeScript 测试。Jest 提供了内置的覆盖率收集功能,无需额外配置即可生成详细的覆盖率报告。
前提条件
安装所有必要的依赖,包括:
-
jest- 测试框架 -
ts-jest- TypeScript 支持 -
@jest/globals- Jest 全局类型 -
jest-environment-jsdom- DOM 环境支持 -
@types/jest- TypeScript 类型定义
验证依赖安装
检查 node_modules 目录是否存在,或运行:
pnpm list jest ts-jest
项目配置
Jest 配置文件
-
文件位置:
jest.config.ts(项目根目录)
配置参考:
import type { Config } from 'jest';
const config: Config = {
// 使用 ts-jest 预设
preset: 'ts-jest',
// 测试环境
testEnvironment: 'jsdom',
// 根目录
rootDir: '.',
// 测试文件匹配模式
testMatch: [
'**/__tests__/**/*.test.ts',
'**/__tests__/**/*.test.tsx',
'**/?(*.)+(spec|test).ts',
'**/?(*.)+(spec|test).tsx'
],
// 模块文件扩展名
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
// 模块路径映射(根据项目结构调整)
moduleNameMapper: {
'^xxxx$': '<rootDir>/packages/xxxx/src',
'^@xxxx/(.*)$': '<rootDir>/packages/xxxx/src/$1',
},
// 转换配置
transform: {
'^.+\\.tsx?$': [
'ts-jest',
{
tsconfig: {
// 测试环境需要的额外配置
module: 'commonjs',
esModuleInterop: true,
allowSyntheticDefaultImports: true,
target: 'ES5',
strict: true,
skipLibCheck: true,
moduleResolution: 'node',
sourceMap: true,
},
},
],
},
// 覆盖率配置
collectCoverageFrom: [
'packages/**/src/**/*.{ts,tsx}',
'!packages/**/src/**/*.d.ts',
'!packages/**/src/**/__tests__/**',
'!packages/**/src/**/*.test.{ts,tsx}',
'!packages/**/src/**/index.ts', // 通常不测试入口文件
],
// 覆盖率报告目录
coverageDirectory: '<rootDir>/coverage',
// 覆盖率阈值(可选,根据需要调整)
// coverageThreshold: {
// global: {
// branches: 80,
// functions: 80,
// lines: 80,
// statements: 80,
// },
// },
// 忽略的目录
testPathIgnorePatterns: [
'/node_modules/',
'/dist/',
'/coverage/',
],
// 清除 mock
clearMocks: true,
// 恢复 mock
restoreMocks: true,
// 显示覆盖率
collectCoverage: false,
// 详细输出
verbose: true,
};
export default config;
TypeScript 配置
-
文件位置:
tsconfig.json(项目根目录) -
要求:启用
strict: true模式
package.json 脚本
-
文件位置:
package.json(项目根目录) -
要求:包含
test:coverage脚本 -
当前配置:
{ "scripts": { "test:coverage": "jest --coverage" } }
快速开始
1. 运行覆盖率检测
在项目根目录执行以下命令:
# 生成覆盖率报告
pnpm test:coverage
# 或者只测试 xxxx 包
pnpm test:xxxx --coverage
2. 查看覆盖率报告
运行完成后,覆盖率报告会生成在 coverage/ 目录下:
-
HTML 报告:打开
coverage/lcov-report/index.html在浏览器中查看详细的覆盖率报告 - 终端输出:命令执行完成后,会在终端显示覆盖率摘要
3. 覆盖率指标说明
Jest 会报告以下四个覆盖率指标:
- Statements(语句覆盖率):已执行的语句百分比
- Branches(分支覆盖率):已执行的分支(if/else、switch 等)百分比
- Functions(函数覆盖率):已调用的函数百分比
- Lines(行覆盖率):已执行的行百分比
当前配置
项目已配置了 Jest 覆盖率收集,配置位于 jest.config.ts:
// 覆盖率配置
collectCoverageFrom: [
'packages/**/src/**/*.{ts,tsx}',
'!packages/**/src/**/*.d.ts',
'!packages/**/src/**/__tests__/**',
'!packages/**/src/**/*.test.{ts,tsx}',
'!packages/**/src/**/index.ts', // 通常不测试入口文件
],
// 覆盖率报告目录
coverageDirectory: '<rootDir>/coverage',
包含的文件
-
packages/**/src/**/*.{ts,tsx}- 所有 TypeScript 源文件
排除的文件
-
*.d.ts- TypeScript 声明文件 -
__tests__/**- 测试文件目录 -
*.test.{ts,tsx}- 测试文件 -
index.ts- 入口文件(通常只做导出)
设置覆盖率阈值
可以在 jest.config.ts 中启用覆盖率阈值,确保代码质量:
coverageThreshold: {
global: {
branches: 80, // 分支覆盖率至少 80%
functions: 80, // 函数覆盖率至少 80%
lines: 80, // 行覆盖率至少 80%
statements: 80, // 语句覆盖率至少 80%
},
},
启用后,如果覆盖率低于阈值,测试将失败。
查看详细报告
HTML 报告
- 运行
pnpm test:coverage - 打开
coverage/lcov-report/index.html - 在浏览器中浏览:
- 文件列表视图:查看每个文件的覆盖率
- 文件详情视图:查看哪些行被覆盖,哪些未覆盖(红色=未覆盖,绿色=已覆盖)
终端输出示例
-------------------|---------|----------|---------|---------|
File | % Stmts | % Branch | % Funcs | % Lines |
-------------------|---------|----------|---------|---------|
All files | XX | XX | XX | XX |
utils/ | XX | XX | XX | XX |
file.ts | XX | XX | XX | XX |
guid.ts | XX | XX | XX | XX |
-------------------|---------|----------|---------|---------|
其他有用的命令
# 只运行测试(不生成覆盖率)
pnpm test
# 监视模式运行测试
pnpm test:watch
# 只测试 uploader 包
pnpm test:uploader
# 生成覆盖率并只显示摘要(不生成 HTML)
jest --coverage --coverageReporters=text
覆盖率报告格式
Jest 默认生成以下格式的报告:
-
lcov - 用于 CI/CD 集成(
coverage/lcov.info) - text - 终端输出
- text-summary - 终端摘要
-
html - HTML 报告(
coverage/lcov-report/index.html)
可以在 jest.config.ts 中自定义:
coverageReporters: ['text', 'lcov', 'html', 'json-summary'],
CI/CD 集成
覆盖率报告可以集成到 CI/CD 流程中:
-
GitHub Actions:使用
actions/upload-artifact上传coverage/目录 -
Codecov:上传
coverage/lcov.info到 Codecov -
Coveralls:上传
coverage/lcov.info到 Coveralls
注意事项
- coverage 目录已添加到 .gitignore,不会提交到版本控制
- 覆盖率报告会显示所有源文件,包括未测试的文件
- 某些文件(如类型定义、入口文件)可能不需要 100% 覆盖率
- 覆盖率只是质量指标之一,不能完全代表代码质量
提高覆盖率
- 识别未覆盖的文件和函数
- 为关键业务逻辑编写测试
- 测试边界情况和错误处理
- 使用覆盖率报告找出遗漏的测试场景