用途
本技能用于有意义的度量与改进测试覆盖率,而非单纯追求覆盖率数字。它覆盖覆盖率提供者的选择与配置、基于风险的缺口分析、以及在 CI 中将覆盖率作为门禁(gate)的完整方法。
主要能力
覆盖率工具选择与配置:按测试运行器选择覆盖率提供者。Vitest 使用 @vitest/coverage-v8(默认)或 @vitest/coverage-istanbul;Jest 内置(coverageProvider 可选 v8 或 babel);非 Vitest 的 Node 项目(node:test、mocha)使用 c8 CLI;旧式 Istanbul CLI 使用 nyc;Python 使用 pytest-cov(封装 coverage.py)。底层有 V8 与 Istanbul 两种引擎:V8 内置于引擎、不插桩源码、更快;Istanbul 插桩源码、较慢但在转译器/打包器下映射更可靠。当 V8 映射不佳(报告未覆盖行落在空行、闭合括号或装饰器上)时应切换到 Istanbul。
跨测试类型合并覆盖率:单元、集成、E2E 各自产生部分覆盖率,需合并后对合并总量设门禁。Vitest 可用多项目合并;nyc 用 nyc merge .nyc_output merged.json && nyc report -t merged;coverage.py 用 coverage combine。
覆盖率报告类型:text(终端)、html(交互式)、lcov(对接 SonarQube/Codecov/Coveralls)、json-summary(CI 脚本、PR 评论)、cobertura(GitLab CI)。
缺口分析:按未覆盖行排序文件(取前 20),并将缺口映射到风险等级——支付处理、认证/权限为关键级,应立即写测试;数据校验、错误处理为高级;工具函数为中级;UI 格式化为低级;生成代码排除。排序需包含分支覆盖率而非仅行覆盖率。
覆盖率作为 CI 门禁:设置全局阈值作为项目最低线,再对关键代码(支付、认证)设置更严格的按目录阈值。采用棘轮模式:记录当前覆盖率为最低阈值,每个 PR 必须达到或超过它,覆盖率只升不降。PR 差异覆盖率门禁要求 PR 中新增代码达到更高阈值(如 90%)。
变异测试:衡量断言质量而非仅代码执行。Stryker JS v9.6+ 和 Vitest 4.1+ 可增量运行于 PR 变更文件;mutmut 3.x 覆盖 Python。变异分数 80% 表示捕获了 80% 注入的 bug。
有意义的覆盖率 vs 虚荣覆盖率:75–85% 是多数项目的甜点区,关键路径(支付、认证)目标 90%+。应排除 .d.ts、桶导出 index.ts、Storybook stories、生成代码、数据库迁移、测试 mock、类型模块等,并在文档中记录每个排除项的理由。
核心原则
- 覆盖率衡量广度而非深度——行被执行不等于被正确测试。
- 分支覆盖率比行覆盖率更重要——单行三元表达式行覆盖 100% 但分支覆盖可能仅 50%。
- 棘轮模式:只升不降。
- 按风险聚焦缺口,而非数字——85% 的项目未必优于 75%,关键看未测试部分是否含支付、认证或数据完整性逻辑。
- 新代码门槛高于遗留代码——PR 新代码要求 90%+,即使项目整体仅 65%。
使用方式
按「快速路由」索引:选择配置覆盖率提供者参考 tool-config.md;决定下一步在哪写测试用缺口分析;防止 CI 回退用棘轮模式;向评审者展示每 PR 覆盖率用 PR Diff。发现阶段需先检查 .agents/qa-project-context.md。验证时需证明门禁确实会在回退时失败(临时降低某指标或删除一个通过的测试,确认退出码非零)。
适用场景
需要建立可靠覆盖率门禁、避免覆盖率随时间衰减、或区分有效测试与虚荣指标的工程团队。
限制
资料未提供具体价格、收费模式或商业授权信息;变异测试在完整代码库上成本高昂,需增量运行;100% 覆盖率通常不切实际且会导致脆弱、琐碎的测试。