不可达代码应被静态分析工具(如 rome 的 nounreachable 规则)识别并消除,而非依赖单元测试覆盖;覆盖率工具仅报告未执行行,不判断逻辑可达性,需结合 html 报告与 ci 中的 lint 检查共同治理。

JavaScript 单元测试中无法到达的代码(unreachable code)本身不是“需要标记”的目标,而是应当被识别、分析并消除的问题。覆盖率工具(如 Istanbul / nyc、Jest 内置的 coverage)不会主动帮你“标记”不可达代码——它只会如实报告某行未被执行;真正能识别出“逻辑上永远不可能执行”的,是静态分析工具(比如 Rome 的 noUnreachable 规则)。
别靠测试“覆盖”不可达代码,先让它不存在
不可达代码在单元测试里根本不会运行,所以无论你写多少用例,覆盖率报告都只会显示“未覆盖”,但不会告诉你“这行本就不该存在”。它的根源是控制流缺陷,例如:
-
return后紧跟语句:function f() { return 1; console.log('dead'); } -
throw后还有代码:if (err) throw new Error(); doSomething();(当err为真时,doSomething()永远不执行) - 无条件
break/continue后的循环体剩余部分
这类代码不是“难测”,而是“不该存在”。Rome 的 noUnreachable 规则会在 lint 阶段基于控制流图(CFG)直接报错,提示你删掉它们——这才是正确起点。
用 Istanbul / Jest 看清哪些行“疑似不可达”
虽然覆盖率工具不判断可达性,但高亮的“未覆盖行”如果出现在明显控制流终结之后(比如函数末尾 return 后、if 分支内 throw 后),就值得怀疑。启用详细 HTML 报告:
- Jest:运行
jest --coverage --coverageReporters=html,打开coverage/lcov-report/index.html - 观察红色高亮行的位置和上下文,结合代码逻辑判断是否本就不该执行
- 注意排除真实条件分支(如
if (process.env.NODE_ENV === 'dev'))导致的合理未覆盖
配合 Rome 或 ESLint 主动拦截
把 noUnreachable 加入 CI 流程,让它在提交前就拦住不可达代码:
- Rome 配置(
rome.json)中确保启用了 recommended 规则集,该规则自 v0.7.0 起默认开启 - 或显式启用:
"js/noUnreachable": "error" - 与 Jest 并行运行:
rome check . && jest,让静态分析守第一道门
这样,单元测试只需专注验证“应该运行的逻辑”,不用费力去“覆盖”本就不该存在的代码。
特殊情况:有意排除的逻辑块
极少数场景下,你可能保留一段暂时不执行的代码(如降级兜底、实验性开关)。这时不应靠测试“覆盖”,而应明确标注并跳过静态检查:
- 用 Rome 注释抑制:
// rome-ignore noUnreachable: legacy fallback path - 避免用
/* istanbul ignore next */这类仅针对覆盖率的注释——它掩盖问题,不解决问题 - 务必附带清晰理由,并定期清理过期的忽略项
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











