先别急着补测试,搞清楚现状
项目跑完测试,报告弹出来:覆盖率65%。团队群里安静了几秒,有人开始冒泡:‘这不行啊,得赶紧补测试。’然后大家一头扎进写test case的循环里,结果改两天代码,覆盖率涨了5%,又卡住了。
问题不在写不写测试,而在为什么低。有些模块压根没人动过,覆盖率自然低;有些是逻辑复杂,几个分支走不到;还有些是接口依赖外部服务,测起来费劲。一刀切要求‘必须到80%’,只会让开发堆出一堆形同虚设的测试——比如只调用函数不验证结果,或者mock满天飞,看着绿油油,其实没用。
拆开看,哪部分拖了后腿
打开覆盖率报告,按模块排序。很可能发现80%的低覆盖集中在20%的文件里。比如一个老订单处理类,三百行代码,嵌套if三层,还混着数据库和HTTP调用。这种就是‘难啃区’。
先把容易提升的拿下:新写的工具函数、纯逻辑方法,补几个断言很快就能把整体拉高几个点。再集中火力对付重灾区。这时候别想着一口吃成胖子,拆成小任务:今天理清状态流转,明天分离可测逻辑,后天引入依赖注入方便mock。
提高可测性,比写测试更重要
有个常见场景:一个方法又查数据库、又发消息、又算价格。想测?光setup就得十几行mock。与其硬着头皮写,不如花半小时重构:把计算逻辑抽出去,变成独立函数。这个函数没有副作用,输入参数,返回结果,测起来就轻松多了。
function calculateDiscount(price, userLevel) {
if (userLevel === 'vip') {
return price * 0.8;
}
return price;
}
// 测试变得简单直接
test('vip用户享8折', () => {
expect(calculateDiscount(100, 'vip')).toBe(80);
});代码改得好,测试自然好写。有时候少写点耦合,比多写点test文件更有效。
设定合理目标,分阶段推进
不是所有代码都非得80%。启动脚本、配置文件、自动生成的代码,没必要强求。可以约定核心业务模块(比如支付、库存)必须达标,其他区域放宽到60%。
在CI流程里加个检查:新提交的代码,新增部分覆盖率不得低于70%。这样不会为历史包袱焦头烂额,又能防止问题恶化。慢慢把老代码在迭代中顺手优化,积少成多。
见过一个团队的做法:每周站会公布各模块覆盖率变化,谁的模块提升了,掌声鼓励。没强制惩罚,但大家都悄悄开始优化。三个月后,整体从62%升到78%,重点模块全达标。