电脑知识铺
第二套高阶模板 · 更大气的阅读体验

测试覆盖率没达标怎么办?端口映射项目里的真实救急法

发布时间:2026-02-10 17:21:33 阅读:103 次

端口映射功能时,跑完单元测试发现覆盖率才62%,CI流水线直接红了——这事儿我上周刚踩过坑。

先别慌,看看是哪块漏了

不是所有代码都得100%覆盖。比如你写了个 checkPortAvailability() 方法,调用系统 netstatss 命令查端口占用,这种跟系统命令强耦合的逻辑,真实环境里可能因权限、路径、输出格式不同而分支跳转——但你本地 mock 不全,就容易漏掉 stderr 非空、返回码为1却没报错这些分支。

举个例子:

function checkPortAvailability(port) {
return execSync(`ss -tuln | grep :${port}`, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] })
.trim()
.length > 0
? false // 端口已被占用
: true;
}

这段代码看似简单,但实际运行中:execSync 可能抛异常(命令不存在、权限不足)、grep 没匹配到时返回空字符串、ss 输出格式在不同Linux发行版里还不一样……这些路径,光靠 happy path 测试根本扫不到。

快速补漏三招

第一招:抓日志反推。把端口映射服务跑起来,手动触发几个典型场景(比如映射已占用端口、映射非法IP、配置文件缺失),看控制台报什么错、堆栈在哪断的。哪个函数没进 catch?哪个 if 分支压根没走?记下来,针对性补 case。

第二招:用 Istanbul 看热力图。加一句 nyc --reporter=html npm test,打开生成的 coverage/index.html,红色高亮的地方就是裸奔代码。我上次发现 parseConfigFile() 里对 YAML 格式错误的处理逻辑整整7行从没被执行过——因为测试用的全是合法 YAML。

第三招:绕过“不可测”,改写关键逻辑。像上面那个 checkPortAvailability,与其死磕系统命令的各种异常,不如抽成接口:

class PortChecker {
constructor(executor = execSync) {
this.exec = executor;
}
check(port) { /* ... */ }
}

测试时传个模拟函数:new PortChecker((cmd) => { throw new Error('command not found'); }),立刻就能覆盖异常流。

别硬刚100%,盯住核心路径

端口映射的核心是:配置加载 → 端口校验 → iptables/nft 规则写入 → 状态反馈。这四步的主干逻辑必须覆盖全,尤其是规则写入失败后的回滚动作——这才是线上出事时救命的代码。至于日志打点、配置字段的默认值填充这些辅助逻辑,覆盖率低点真没关系。

有次我们上线前发现 iptables -t nat -A PREROUTING 执行失败但没 rollback,结果新规则挂了,老规则还留着,流量直接黑洞。后来补了一个只 mock execSync 返回错误码的测试,覆盖率+3%,更重要的是堵住了这个坑。