你的 AI 写的测试永远不会失败

你让 AI 写测试。它给了你 12 个绿色的测试。你的 CI 通过了。你合并了代码。三天后,一个 Bug 进入了生产环境。你查看测试。它们都通过了,但它们什么都没测到。

绿色的测试不是证明。它只是一个假设。AI 写出的假设永远不会失败。

看这个函数:

func Discount(total int) int {
    if total > 100 {
        return total - 10
    }
    return total
}

AI 可能会写出这样的测试:

func TestDiscount(t *testing.T) {
    got := Discount(150)
    if got < 0 {
        t.Errorf("result should not be negative")
    }
}

这个测试是绿色的。它运行了代码,所以你的覆盖率看起来很好。但这个测试只检查结果是否小于零。如果你把折扣逻辑改成了数学错误,测试依然是绿色的。它没有检查行为。它只是在检查“灯是否亮着”。

这是一个陷阱。覆盖率统计的是你触及的代码行。它并不统计那些真正重要的断言。90% 的覆盖率报告可能会掩盖损坏的代码。

AI 追求的是通往“绿灯”的最短路径。它会选择软断言和那些什么都不测的 Mock。

要解决这个问题,请遵循一个规则:检查测试是否知道如何失败。

有意地修改你的代码。如果测试依然是绿色的,那么这个测试就是没用的。把它扔掉。

一个真正的测试应该是这样的:

func TestDiscount(t *testing.T) {
    if got := Discount(150); got != 140 {
        t.Errorf("Discount(150) = %d, want 140", got)
    }
}

如果你破坏了逻辑,这个测试会立即变红。它能抓到错误。

你不可能为每个测试都手动这样做。请改用变异测试(Mutation Testing)。像 Go 语言中的 Gremlins 这样的工具会对你的代码进行微小的改动。它们会检查你的测试是否能捕捉到这些改动。

如果一个改动没有导致测试失败,说明你的测试套件中存在漏洞。

我在处理 AI 代码时会这样做。我不会让 AI 宣布工作已完成。我会设置一个门禁。工具会对代码进行变异。如果测试依然是绿色的,AI 必须重写它。AI 不能决定测试是否优秀,变异结果才能决定。

没有一个 AI 测试能在证明自己可以失败之前进入我的代码库。一个无法失败的测试比没有测试更糟糕。缺失的测试是显而易见的,而虚假的测试则是危险的。

不要再迷信绿灯了。测试的价值仅在于它能产生的“红色”。

Source: https://dev.to/ohugonnot/your-ai-writes-tests-that-can-never-fail-3i57

Optional learning community: https://t.me/GyaanSetuAi