智汇 IT
城启新篇

从踩坑现场拆解单元测试覆盖率提升方法

上周跟南京河西某互联网公司的后端组吃鸭血粉丝,几个人刚熬了两个大夜,眼底下乌青一片。为啥?上线前QA卡了覆盖率指标,之前他们整个项目的单元测试覆盖率才32%,离要求的80%差了快一半。一开始几个人兴冲冲熬了通宵,把覆盖率冲到了79%,结果QA扫了一遍用例,直接打回——一半的测试都是给DTO的getter setter凑的数,根本碰不到业务逻辑。

先把假覆盖率的遮羞布扯了

说真的,这种操作我见太多了。 谁没为了过考核写过几行没用的测试代码啊。 给返回固定字符串的静态方法写三个用例,给没有任何逻辑的成员变量写getter测试,甚至直接在测试文件里把源码类import进来,哪怕一行执行逻辑都没有,覆盖率工具照样给你算进统计数里。
单元测试无效用例凑数示意图
单元测试无效用例凑数示意图
我之前碰到个开发,为了把自己负责的模块覆盖率从40%刷到70%,专门给一个返回用户昵称的get方法写了四个测试:测空字符串,测正常中文昵称,测带emoji的昵称,测超长昵称。那方法本身就一行return user.nickname,没有任何判断逻辑。写这些测试花了他两个小时,半毛钱实际价值没有。 你哪怕把所有空方法、常量类的行都用测试跑一遍,下次线上出了金额计算的错,该赔还是赔,该炸还是炸。这种刷出来的覆盖率,本质就是给自己的考核交差,跟代码质量半毛钱关系没有!

从核心业务链路倒推要补的测试

别一上来就盯着代码行数算覆盖率缺口。 你先拉过去半年的线上故障清单出来,把所有出过生产问题的模块列出来,优先级从高到低排。我见过最聪明的团队,从来不会先给简单的CRUD接口补测试,他们第一时间补的,就是那些曾经出过线上事故、涉及资金计算、用户状态流转的核心模块。 比如之前那个做本地生活的团队,去年三个月里因为优惠券满减计算错了三次,每次都要给用户发补偿券,前后赔了快十万。那他们肯定先把满减计算的所有分支测透:跨店满减和店铺满减的优先级对不对?优惠券叠加的时候有没有把上限算错?用户取消订单的时候优惠券能不能正确退回?这些分支测明白了,哪怕其他边角模块的覆盖率低一点,也比你把所有时间花在给头像字段写校验测试上强。
核心业务链路单元测试覆盖优先级矩阵图
核心业务链路单元测试覆盖优先级矩阵图
这里有个很容易踩的坑:别光追求行覆盖率,多盯着分支覆盖率。很多人写测试只测正常流程,比如输入合法参数的时候接口能返回正确结果,但是根本不测异常分支:参数为空的时候会不会抛可控的异常?第三方支付接口超时的时候能不能走降级逻辑?循环里的边界条件会不会触发数组越界?这些没人测的异常分支,往往就是线上故障的根源。 而且别等着上线前熬夜突击补测试。每天写业务代码的时候,顺手抽20分钟给当天改的模块补两个测试,测测你自己写的逻辑里最容易出错的地方。比你上线前熬一整夜补一百个凑数的用例有用一百倍。

别把覆盖率当KPI硬卡

别把覆盖率当KPI硬卡
别把覆盖率当KPI硬卡
我见过太多团队,覆盖率提不上来的根本原因,就是从一开始就把这个指标当KPI卡人。 比如定个死线,你负责的模块覆盖率不到75%,不许合并代码,不到就扣绩效。结果呢?大家为了过考核,开始想尽办法钻覆盖率工具的空子:给生成的代码写测试,把工具类从排除名单里删掉硬算,甚至直接改覆盖率工具的配置文件,把统计阈值调低。最后数字好看了,代码该有bug还是有bug。 之前在徐庄软件园碰到个做企业服务的技术负责人,他们团队从来不给个人定覆盖率指标。每次迭代上线前,只查两件事:核心链路的测试通过率是不是100%,有没有新改的逻辑没补对应的测试。他们整个项目的平均覆盖率才62%,但是线上故障率比同行低了快60%。说白了,覆盖率只是个参考工具,不是最终目的。你哪怕覆盖率只有50%,只要把所有容易出问题的分支都测透了,比那种硬凑到100%但全是无效用例的代码靠谱得多。 对了,记得把那些根本不需要测试的类从覆盖率统计里排除掉:自动生成的DTO类,包装第三方SDK的薄封装类,简单的常量配置类。别让大家把时间浪费在这些没必要的测试上。 上次跟河西那几个后端组的人聊完,他们回去把之前凑的那几百个没用的测试全删了,先集中把订单金额计算的三个核心模块的分支全测透。现在项目覆盖率是58%,昨天上线前QA扫了一遍,找不出来任何明显的逻辑漏洞。比之前硬凑到80%的时候,踏实多了。
免责声明:市场有风险,选择需谨慎!此文仅供参考,不作买卖依据。如有侵权请联系删除。
文章名称:从踩坑现场拆解单元测试覆盖率提升方法
文章链接:https://www.itcdj.com/it/395.html