单元测试需要覆盖所有代码吗
写代码的时候,很多人一听到“单元测试覆盖率要达到100%”,心里就开始打鼓。是不是每一行代码都得被测到?不覆盖完就不是好项目?其实没那么绝对。
拿一个简单的登录功能来说,你写了判断用户名不能为空、密码不能少于6位、还要验证验证码是否正确。这些核心逻辑当然要测,不然上线后用户输个空账号直接崩了,那可就尴尬了。
关键路径必须覆盖
真正重要的,是把业务的关键路径测全。比如处理订单金额的计算函数:
function calculateTotal(items, taxRate) {
if (!items || items.length === 0) return 0;
const subtotal = items.reduce((sum, item) => sum + item.price * item.quantity, 0);
return subtotal * (1 + taxRate);
}这个函数里的条件判断、循环累加、税率计算,都是影响最终结果的核心部分,不写测试很容易埋雷。尤其是当别人后续修改时,有测试才能快速发现问题。
边角料代码不必强求
但有些代码真没必要死磕覆盖率。比如自动生成的DTO类、简单的getter/setter、或者框架要求必须存在但实际不执行逻辑的空方法。为了凑100%写一堆毫无意义的测试,反而浪费时间。
再比如一段已经被标记为@Deprecated的旧代码,马上就要删了,这时候还花精力去补测试,显然不划算。
更现实的情况是,团队赶版本,优先保证主流程稳定才是正道。追求100%覆盖率容易变成形式主义,报告看着漂亮,实际防御力未必高。
质量比数字更重要
有时候覆盖率显示95%,但测试全是走形式,只调用一下方法并不验证结果,这种“假覆盖”比没测还危险。相反,哪怕只有70%,但每一条测试都精准打击潜在风险点,这样的项目反而更稳。
所以别被数字绑架。关注哪些代码出问题会影响用户、哪些改动容易引发连锁错误,把这些地方守住,比盯着报表上的百分比有意义得多。
单元测试的目标不是取悦指标,而是帮你早点发现bug,让重构更有底气。该测的测到位,无关紧要的放过,这才是正常人的开发节奏。