单元测试是程序员的隐形兜底

上周帮前同事擦屁股,擦到凌晨三点。

他们团队刚上线的满减叠优惠券模块出了大问题,用户凑199的订单,最后实付1块9。整个排查过程翻了三个小时代码才发现,是财务临时改了个优惠触发的阈值,没人记得之前写的边界测试用例早就没人维护了。

没人写的测试用例到底在防什么

很多人对单元测试的偏见根深蒂固——觉得这是大厂搞出来的形式主义,是耽误开发效率的负担。我带过的应届生就直白说过,”我把主流程跑通就交差,等QA测出来bug我再改呗”。结果上次改支付回调逻辑,他顺手把老用户的退款校验分支给注释了,上线三天收到两百多笔退款失败的投诉。

其实单元测试从来不是给QA写的,也不是给领导看的覆盖率报告凑数的。它是给三个月后改代码的你自己写的。你三个月后回来看自己写的满减逻辑,谁记得当时为什么要在满200减30的规则里留个1分钱的阈值?谁记得用户用了储值卡之后优惠券的抵扣顺序?你改了一行代码,跑一遍测试用例,哪个边界错了直接弹红,总比你上线了被用户追着骂、被运营堵在工位上强。

电商订单金额计算单元测试代码截图
电商订单金额计算单元测试代码截图

大部分人写的单元测试都是无效劳动

我见过太多为了凑覆盖率写的测试用例,纯纯的无效劳动。比如给一个只有一行的字符串处理函数写八个测试,全是测正常输入,连个null值都没覆盖;比如写测试的时候把实现逻辑硬编码进去,现在函数满减是减10块,测试用例就写”预期输出减10块”,等业务改了满减规则,测试跟着一起改,那这测试有个屁用?

最离谱的一次,我帮团队审测试用例,发现一个计算订单金额的函数,测试用例全是测订单金额大于100的场景,连个0元订单、负数金额的情况都没测。后来这个函数对接第三方支付的时候,传了个空的金额值,直接把整个支付链路干挂了四十分钟,损失的流水够给这个模块写一百份测试用例。

IDEA单元测试覆盖率报告彩色界面
IDEA单元测试覆盖率报告彩色界面

很多团队追求测试覆盖率拉到90%以上,实际点开报告看,全是测的无足轻重的工具函数,核心的边界值一个没碰。这种覆盖率除了写周报好看,半毛钱用都没有。

怎么写才不浪费时间

别搞极端,不是所有代码都需要写单元测试。你写个页面的静态文案,临时改个活动的展示样式,硬凑测试用例纯纯浪费时间。核心业务逻辑优先写测试——比如计算订单金额、用户权限校验、数据格式转换这些,错一点就要出资损、出安全问题的模块,必须把边界场景覆盖全。

还有个很多人踩的坑:测试用例不要测实现,要测行为。什么意思?就是你别管这个函数内部是用循环算的还是用递归算的,你只要明确输入对应的预期输出就行。比如你写个满减计算函数,输入”订单金额200,普通用户,一张50元无门槛券”,预期输出”实付150″,这就对了。你别写测试的时候去断言函数内部的某个临时变量值是多少,不然以后你重构代码,哪怕逻辑完全正确,测试也会挂,最后没人愿意维护,整个测试套件就成了摆设。

还有个最省事的方法:每次修完bug,顺手补个对应的测试用例。上次出了满减叠券的bug,你修完代码,第一时间把这个触发bug的边界场景写成测试用例存下来。下次再有人改这块的逻辑,碰到同样的问题,测试直接就拦住了。比你写十篇复盘报告有用多了。

说实话,我之前也觉得单元测试是脱离业务的形式主义。直到有次我改了个后台权限校验的逻辑,本来以为没问题,跑测试的时候才发现,之前预留的内部运营账号的权限被我改没了——要是真上线,运营拿不到后台发不了活动,我估计得被追着骂一周。

上周擦完屁股的那个前同事,昨天给我发消息,说他们现在把所有优惠计算的模块都补了边界测试,这两周上线再也没出过金额类的bug。

哪有什么银弹啊。

不过是你现在多花二十分钟写的测试,省得以后花二十个小时擦屁股而已。

免责声明:市场有风险,选择需谨慎!此文仅供参考,不作买卖依据。如有侵权请联系删除。
文章名称:单元测试是程序员的隐形兜底
文章链接:https://m.itcdj.com/it/187.html