我把代码库里三个永远不会报错的“假检查”给揪出来了
我最近在复盘代码库时发现了三个这种典型的“无效检查”,虽然它们看起来像在工作,但其实完全是摆设。
第一种是那种“自己检查自己”的验证器。有个页面在讲格里高利历的闰年规则,下面配了一段 isLeap 的实现。验证器本来应该检查这个实现对不对,结果验证器内部居然直接抄了一份一模一样的逻辑。这意味着如果原代码有 Bug,验证器里的副本也会有同样的 Bug。两者达成共识,结果就是页面上有两个阻塞性缺陷,但测试面板却显示 17 项全部通过。
这种坑在 Code Review 时很难发现,一个简单的判断标准是:这个检查函数到底有没有接收它要检查的对象?如果它什么都没导入,只是在运行一套私有的逻辑,那它就是在自我安慰。
第二种是我觉得最讽刺的,它出现在一个专门讨论“不可失败验证器”的页面上。页面底部会显示一个分数,比如 Pinned result: PASS 109/109。验证器会检查这个字符串是否正确,但它构建预期结果的代码是这样的:
const want = 'PASS ' + (checks + 1) + '/' + (checks + 1);发现问题了吗?PASS 是写死的字符串,它根本没去对比实际的判定结果,只是在确认页面知道文件里有多少个断言。结果就是页面显示 PASS,但验证器实际运行结果是 FAIL,这种情况居然持续了两周。
我把它改成了这样,让它真正去读失败次数:
const total = checks + 1;
const want = (failures ? 'FAIL ' : 'PASS ') + (total - failures) + '/' + total;第三种最隐蔽,就是那种“只要结果像那么回事就通过”的估计器。我们在处理齐夫定律(Zipf's law)的页面上用了一个连续最大似然估计量,但引用的是离散估计量的文献。因为结果算出来在 1.9 左右,正好落在我们设置的 [1.5, 2.8] 这个宽泛的范围内,所以 21 个检查全部通过。直到我拿公开数据集对比,才发现这个估计量已经错了两年,但因为判定区间给得太宽,它永远不会触发报警。
总结来看,这三种失效的共性就是:断言的右侧(预期值)是随着被测代码同步变化的。无论是复制逻辑、依赖计数还是设置过宽的阈值,只要预期值会跟着代码“跑”,这个测试就失去了意义。