单元测试都过了,为什么系统上线还是崩?代码走查如何帮你补齐最后一道防火墙?

2026-09-24

单元测试覆盖率冲到90%以上,CI流水线全绿,代码合并到主分支,上线。

然后系统崩了。

这种情况在软件行业里不算罕见。单元测试跑得再好,也拦不住某些类型的缺陷。它们不藏在单个函数里,藏在函数与函数的缝隙之间,藏在开发者的思维盲区里,藏在“我没想到用户会这么操作”的角落里。

单元测试.jpg

单元测试

一、单元测试的天然盲区

单元测试的本质是验证“给定输入,函数是否返回预期输出”。它测的是单个模块的行为。但系统上线后出问题,往往不是某个函数算错了数,而是这些情况:

模块A返回了正确的数据,模块B也能正确处理数据,但A和B对同一个字段的理解不一样。A认为status=1表示“已支付”,B认为status=1表示“待支付”。单元测试单独跑A和B都过,合在一起就出问题。

或者,某个函数在测试环境里从来没被传入过空值,因为测试用例没设计这个场景。上线后用户一提交空表单,直接空指针异常,整个页面白屏。

再或者,代码里写死了一个测试环境的配置,比如timeout=100ms。测试环境内网延迟不到10毫秒,跑得很好。上线后跨机房通信延迟200毫秒起步,所有请求超时。

这些问题,单元测试抓不住。

二、代码走查补的是哪道墙?

代码走查,就是让人去看代码,而不是让机器去跑代码。它是静态的,不运行程序,但恰恰因为“不运行”,它能发现那些“运行起来才暴露”的问题的上游原因。

单元测试问的是“这个函数对不对”,代码走查问的是“这段代码写得对不对”。

走查的时候,有经验的工程师会关注几件事:

模块之间的接口约定是否一致:A和B对同一个字段的理解是不是一样的?

边界条件是否处理:空值、超长字符串、并发竞争,代码里有没有对应的防御?

配置是否可移植:有没有硬编码的路径、端口、超时时间,换个环境还能不能跑?

异常处理是否完整:catch了异常之后是吞掉了还是记录了日志还是向上抛了,处理方式对不对?

这些问题在单元测试里往往被忽略了,因为单元测试关注的是“正向路径走通”,而代码走查关注的是“异常路径有没有兜住”。

三、为什么代码走查能发现单元测试发现不了的问题?

核心在于视角不同。写单元测试的人,脑子里想的是“我要验证这个函数”,所以测试用例是围绕这个函数的预期行为设计的。而做代码走查的人,脑子里想的是“这段代码在什么情况下会出错”,他们从异常场景、边界条件、模块交互的角度去审视代码,而不是从“验证功能”的角度。

某电商平台的一次真实复盘:单元测试覆盖率92%,但代码走查发现支付模块的退款逻辑里,对“部分退款”和“全额退款”的状态判断有歧义。单元测试只覆盖了全额退款场景,部分退款场景压根没测。走查工程师看到代码里一行 if (refundAmount == orderAmount) 就停了,如果是部分退款呢?else分支里做了什么?翻下去一看,else分支直接把订单状态改成了“已退款”,但金额字段没更新。这个缺陷,单元测试永远测不出来,因为测试用例里根本没有部分退款这条。

四、怎么把代码走查用对地方?

代码走查 (21).jpg

代码走查

第一,聚焦高风险模块。

不是所有代码都值得走查。支付、权限、数据隔离、核心业务逻辑等这些地方出问题的后果最严重,优先查。UI样式、日志格式这些,优先级往后放。

第二,带着清单查。

用一份检查清单代替“想到哪查到哪”。模块接口约定、边界条件、异常处理、配置可移植性、并发安全等,每一项都过一遍,比凭感觉翻代码靠谱得多。

第三,让作者讲代码。

最好的走查方式不是别人去读代码,而是作者自己讲:“我这段代码在做什么、为什么这么设计、有没有考虑过其他方案。”讲的过程中,作者自己往往会发现“等等,这里好像不太对”。

第四,问题闭环。

发现的问题记录下来,按严重程度分级,修完之后要有复测确认。没有闭环的走查,等于白走。

单元测试保底,代码走查补漏。单元测试帮你验证“每个零件都合格”,代码走查帮你确认“零件装在一起不会打架”。两件事都做了,系统上线才敢说“我准备好了”。如果你的项目即将上线,功能测试和单元测试都跑完了,不妨再安排一轮代码走查,它花的时间不多,但可能拦住那个让系统上线当天崩掉的致命缺陷。


标签:单元测试、代码走查

阅读2
分享
下一篇:这是最后一篇
上一篇:这是第一篇
微信加粉
添加微信