单元测试是给三个月后的自己写的

上周三凌晨两点十七分,我被运维的电话炸醒。

是支付回调的bug。就是上周产品经理催了三次、说要赶大促提前上线的那个优惠券核销逻辑,开发为了省时间把上周新加的满减叠加规则直接硬编码进了原有方法,连最基本的分支判断都没测。灰度环境跑出来的结果吓出一身冷汗:用户买100块的东西,用了满100减20的店铺券,叠加一张满20减5的通用券,系统算完账,居然显示平台要倒找用户3块钱。再晚两个小时开全量,资损通道直接就打开了。

爬起来改代码的时候翻提交记录,那个改动的提交信息写着“逻辑简单,手动验证过,不需要补测试”。我当时盯着屏幕差点把键盘砸了。

程序员凌晨对着屏幕改线上bug的实景
程序员凌晨对着屏幕改线上bug的实景

大部分人从一开始就误解了单元测试的边界

我见过最离谱的团队,单元测试覆盖率要求卡到80%,最后大家为了凑数,把实体类的getter、setter方法全写进测试用例,跑一遍全绿,真出问题的时候半毛钱用没有。还有人把单元测试写成了集成测试,连数据库连接、第三方支付接口的mock都要配全,写个测试用例的代码量比业务逻辑还长,写两次大家就烦了,干脆把测试文件夹整个忽略掉。

说白了,单元测试的核心从来不是“测试”这两个字,是“单元”。你要测的从来不是整个接口跑通的流程,是那些独立的、没有任何外部依赖的纯逻辑——比如计算优惠券最终抵扣金额的方法,输入是用户的券列表、订单金额、店铺规则,输出是最终要扣的钱数。这个方法不碰数据库,不调外部接口,你就给它把所有可能的边界值输进去:订单金额刚好卡满减门槛,没有可用的有效券,多张券规则互斥,券已经过了有效期,甚至用户输入的订单金额是个负数。这些分支都测到了,不管外面的调用逻辑怎么改,这个计算核心永远不会算错钱。

单元测试纯函数边界划分示意图
单元测试纯函数边界划分示意图

那些看似省时间的偷懒,最后都要加倍还

之前团队有个做订单系统的老开发,他写的核心逻辑代码,单元测试覆盖率从来都是100%。一开始大家都觉得他磨洋工,同样的需求,别人半天写完提测,他要多花一个小时蹲在那补测试用例,显得比所有人都慢半拍。

结果去年大促前要改订单拆单规则,原来的逻辑只按商品类别拆,现在要加上按仓库库存拆分的判断。他改完核心代码,跑了一遍全量测试用例,十分钟就确认所有原来的分支逻辑都没被破坏,当天就顺顺利利把功能上了。而隔壁组一个开发,同样改物流拦截的逻辑,觉得“已发货订单不能拦截”的判断太简单,没必要写测试,上线后手滑把那行判断给注释了,一天之内三百多个已经发走的订单被系统自动拦回仓库,光协调快递、给用户道歉的客服电话就接了两百多个,算下来花的时间比写测试多了十倍都不止。

说实话,谁没赶过项目进度啊?谁没在deadline面前心里打鼓,觉得“这逻辑这么简单,不会出问题的”?但问题是,你写代码的时候觉得逻辑门清,三个月之后你再回来看这串代码,你能记得当时特意留的那个兼容老用户的特殊判断吗?你能记得那个容易出问题的边界值吗?你不能的。

记忆是靠不住的。

落地的时候别搞成形式主义

很多团队一推单元测试就失败,本质上是从一开始就走偏了。

别一上来就卡死全量代码的覆盖率指标。就先盯最核心的那部分:涉及金额计算的、涉及权限判断的、涉及核心状态流转的逻辑,这些地方出问题就是资损、就是安全漏洞、就是用户投诉,这些代码必须100%覆盖测试。剩下的简单CRUD、页面渲染的逻辑,爱写不写,没人拿这个扣你绩效。

别写那种永远不会失败的测试。我见过有人写测试用例,调用完业务方法之后啥断言都没有,就打印一句“测试执行成功”,这种测试写了还不如不写,纯纯浪费提交仓库的空间。

别把单元测试当成上线前才补的作业。你写业务代码的时候,顺手把几个边界情况想一下,写三五个测试用例,前后也就十分钟的事。等代码堆了半个月,你都快忘了当时的逻辑了,回头再补测试,写出来的东西根本就是瞎凑数,半毛钱防护作用都没有。

之前见过更离谱的,团队把单元测试的数量算进开发的KPI,大家为了拿高分,写一堆没用的测试用例,最后测试文件夹的代码量比业务文件还大,后来做一次代码重构,光改测试就花了整整一周,谁都没捞着好。

上周我们把那个出问题的优惠券计算方法重写了,补了二十三个测试用例,覆盖了所有能想到的叠加、互斥、过期、超门槛的场景。昨天产品又提了新需求,要加上直播间专属券的叠加规则,开发改完核心方法,跑了一遍测试,五分钟就确认所有原来的逻辑都没坏,顺顺利利就上线了。

没人会在你写单元测试的时候给你发奖状。

但当你凌晨不用被电话炸醒,不用对着运维的道歉记录赔笑,不用对着满屏的用户投诉挨个回消息的时候,你就知道这东西到底有啥用。它从来不是写给QA看的作业,也不是领导检查时的摆设,是你给三个月后那个可能要熬夜改bug的自己,留的最靠谱的安全垫。

免责声明:市场有风险,选择需谨慎!此文仅供参考,不作买卖依据。如有侵权请联系删除。
文章名称:单元测试是给三个月后的自己写的
文章链接:https://www.itcdj.com/it/107.html