快速定位JS单元测试未覆盖代码的核心是“报告先行、聚焦红色、逆向验证”:先运行覆盖率工具生成HTML报告,直奔红色高亮行,重点检查else、catch、default、早期返回等逻辑;再反推缺失输入,排除环境判断等伪未覆盖,并加日志或debugger实锤验证。

快速定位 JS 单元测试中未覆盖的代码行,核心是“报告先行、聚焦红色、逆向验证”。别从代码开始猜,先让覆盖率工具把问题显性化。
打开 HTML 覆盖率报告,直奔标红行
运行 npx jest --coverage 或 npx vitest --coverage 生成报告后,打开 coverage/lcov-report/index.html。逐级点进具体文件,所有红色高亮行就是未执行语句。重点盯以下几类:
- if/else 中的 else 块、三元运算符的 false 分支(常因输入固定而跳过)
- catch 和 finally 内部逻辑(多数测试只走成功路径)
- switch 的 default 分支或未列出的 case(如 status 传了 'success' 和 'fail',但漏了 'pending')
-
函数开头的早期返回(如
if (!data) return,但所有测试都传了 data)
对照测试用例,反推缺失的输入条件
看到某一行没亮,立刻回到对应测试文件,问自己三个问题:
- 有没有构造让这个
if条件为 false 的输入?比如函数判断user.age >= 18,就补一个age: 17的测试 - 有没有模拟触发
catch的场景?例如 mock 接口返回Promise.reject(new Error('timeout')) - 有没有覆盖边界值?空数组、
null、undefined、空字符串、负数、极大/极小数值等
排除伪未覆盖,避免白忙活
有些红色不是真遗漏,而是工具或设计使然:
-
环境判断代码:如
if (process.env.NODE_ENV === 'development')在 test 环境下自然不执行 -
绝对不可达路径:如
if (false) { ... }或抛错后紧接的语句(无 try/catch) -
TS 编译辅助代码:
__awaiter、__generator等,可在 Jest 配置中用coveragePathIgnorePatterns忽略 - 动态导入或模块顶层副作用:测试加载方式未触发,需检查是否应改为按需调用
加日志或断点,直接验证执行流
当报告和预期对不上时,最省时间的做法是实锤:
- 在可疑行前加
console.log('✅ reached catch block'),跑对应测试看是否输出 - 在关键分支入口放
debugger,用 VS Code 或浏览器调试器单步走,确认流程是否真的绕开了它 - 特别注意异步逻辑——
await后面的行没亮?大概率是测试没等完就结束了


















