审计 AI 生成的测试:一半的绿色 CI 毫无意义
通过的测试感觉像是证据。但它通常比你想象的要苍白得多。
测试断言代码执行了测试所预期的操作。如果代码和预期是由同一个作者编写的,那么预期就会受到代码的影响。测试之所以通过,是因为它在编写时就是为了通过。
绿色的对勾证明了你的测试与代码保持一致。它并不证明代码是正确的。
当 AI Agent 一次性提交整个 Pull Request 时,这个问题会进一步放大。它们会同时编写实现代码和测试。即使作者变了,那个对勾也不会变得更可靠。
我编写了 mirror_audit.py 来寻找这一差距。它使用 AST 读取测试源码,从不运行代码。它寻找三种常见的模式:
- 重算 (The Recompute):测试使用了与代码相同的公式。这不过是披着伪装的 $f(x) == f(x)$。
- 金标字面量 (The Golden Literal):测试使用了从之前运行中复制的数值。它将测试固定在了代码第一天运行的结果上,包括其中的 Bug。
- 冒烟测试 (The Smoke Test):测试仅检查结果是否不为
None,但缺乏真正的断言。
我针对两套测试套件运行了该工具。
第一套套件旨在镜像实现逻辑。它的镜像率 (mirror-ratio) 为 50.0%。CI 失败了。一半的测试没有提供任何独立的信号。
第二套套件是诚实的。它使用了负面案例和独立的预期。它的镜像率为 0.0%。CI 通过了。
镜像率并不衡量你的 Bug 率。它衡量的是缺失的独立信号。它告诉你,你的绿色 CI 中有多少仅仅是测试套件在随代码“点头附和”。
如果测试计算出的错误结果与实现逻辑一致,测试就会保持绿色。如果测试断言的是真实的契约,测试就会变红并捕获 Bug。
不要只盯着覆盖率看。问问自己:你的测试是否真的可能因为真实的原因而失败?
Source: https://dev.to/alex_spinov/audit-ai-generated-tests-half-of-green-ci-proves-nothing-4bmb
Optional learning community: https://t.me/GyaanSetuAi
