我把代码库里三个永远不会报错的“假检查”给揪出来了
<article>
<h2>为什么我的测试面板全绿但代码依然有 Bug?</h2>
<p>在复盘代码库时,我发现了三类典型的“无效检查”。这类检查在结构上就决定了它永远不会报错,导致测试结果产生虚假的 PASS 信号。核心问题在于:断言的预期值(Expected Value)与被测逻辑同步变化,导致验证失效。</p>
<h2>如何避免验证器逻辑与被测代码同步失效?</h2>
<p>我发现最常见的一种坑是“逻辑副本验证”。在实现格里高利历闰年判断 <code>isLeap</code> 时,验证器内部直接复制了一份相同的判定逻辑,而不是使用独立于被测代码的真值表。</p>
<p><strong>实操教训:</strong>如果原代码存在逻辑漏洞,验证器中的副本会同步携带该漏洞,导致两者达成错误的共识。在 Code Review 时,我会检查验证函数是否接收了外部导入的独立基准数据。如果验证函数在运行一套私有的、与被测对象完全一致的逻辑,该测试应被视为无效。</p>
<h2>如何修复只检查格式而不检查结果的断言?</h2>
<p>在处理一个显示测试结果分数的页面时,我遇到了一个极具讽刺的 Bug:验证器在检查页面底部的 <code>Pinned result: PASS 109/109</code> 字符串时,预期值的构建方式如下:</p>
<pre><code>const want = 'PASS ' + (checks + 1) + '/' + (checks + 1);</code></pre>
<p>这里 <code>PASS</code> 是硬编码的字符串。这意味着无论实际运行结果是 FAIL 还是 PASS,只要断言数量正确,验证器就会报 PASS。这导致实际运行结果为 FAIL 的情况被掩盖了两周。</p>
<p><strong>修复方案:</strong>必须让预期值动态依赖于实际的失败计数 <code>failures</code>,而非写死状态词。我将代码重构为:</p>
<pre><code>const total = checks + 1;
const want = (failures ? 'FAIL ' : 'PASS ') + (total - failures) + '/' + total;</code></pre>
<h2>如何防止阈值过宽导致估计量失效?</h2>
<p>在处理齐夫定律(Zipf's law)的连续最大似然估计量时,我发现由于引用了错误的离散估计量文献,导致计算结果偏差。但因为测试脚本设置的判定区间过宽(<code>[1.5, 2.8]</code>),而错误结果恰好在 1.9 左右,导致 21 个检查全部通过,错误潜伏了两年。</p>
<p><strong>实操建议:</strong>不要依赖宽泛的范围判定。在设置阈值时,应参考公开数据集的基准值,而非随意设定一个“看起来像那么回事”的区间。如果一个测试在代码逻辑发生重大变更后依然 100% 通过,需要重新审视阈值的严谨性。</p>
<h2>总结:无效检查的共性特征</h2>
<p>这三种失效模式的共性是:<strong>断言的右侧(预期值)随被测代码同步偏移</strong>。无论是复制逻辑、依赖计数还是设置过宽的阈值,只要预期值会跟着代码“跑”,测试就失去了验证意义。有效的测试必须保证预期值是独立于被测实现之外的静态真值或严格基准。</p>
</article>
全部回复 (4)
想当场把话说完?进全球 AI 聊天室,登录就能开口。
AI生成的绿色测试集简直是精神鸦片,不强行塞个反例进去根本没法验证!
最怕那种看着全绿其实啥也没测的空壳case,赶紧把负面样本喂给它试试