给一个没有测试的工具函数,让 AI “补齐单元测试”,它通常能很快交出十几条用例,覆盖率也会变好看。问题是数量不等于保护力。有些用例只是在重复实现,有些断言永远不会失败,还有些为了适应错误行为,悄悄把本来应该暴露的 bug 固化成了预期。

AI 最擅长扩展边界清单

我会先写两三条最重要的行为:正常输入得到什么、非法输入如何处理、哪条业务规则不能退化。然后让 AI 阅读实现和已有测试,补充“还缺哪些边界”,先只列清单不写代码。它经常能想到空数组、Unicode、时区边界、重复提交和并发顺序这些容易遗漏的情况。

清单确认后,再选择有意义的项目生成测试。这样人负责测试意图,AI 负责机械展开,分工比较合适。

先不要写测试代码。
根据函数契约列出边界场景,并说明每个场景
可能发现哪类缺陷。不要根据当前实现推测预期。

三种看起来很忙、实际很弱的测试

第一种是把内部实现全部 mock 掉,最后只验证 mock 被调用。它和真实行为相距太远,重构一下就碎。第二种是大快照,几百行输出变化时没人认真看 diff。第三种是没有关键断言,只检查函数“没有抛错”。

AI 还可能读取实现细节后,把现有 bug 当成规范。所以提示里要单独提供函数契约或需求,而不是让它仅凭代码猜。发现测试和需求冲突时,应先停下来确认,不能直接修改断言让绿色回来。

测试通过只能说明实现符合测试;测试是否符合需求,是另一层判断。

生成之后,我会故意让它失败一次

我的流程是:先确定契约;让 AI 提边界清单;挑选用例;生成小批测试;审查断言;最后临时改坏实现,确认关键测试真的会红。这个“故意破坏”很有效,它能立刻发现那些无论实现怎样都通过的空心测试。

评审生成测试时,我也会问三个问题:失败信息能不能看懂?测试是否只关心外部行为?未来合理重构会不会被无关细节阻挡?答不上来就删掉或重写,没必要因为是自动生成就全部保留。

覆盖率的正确位置:它适合提示“哪里完全没走到”,不适合证明“这里已经测好了”。行覆盖到达以后,还要看分支、输入和业务风险。

AI 确实让补测试变快了,尤其是重复数据和边界组合。但它最大的价值不是帮我把数字推到 90%,而是像一个不嫌麻烦的搭档,陪我把“还有哪些情况”多问几遍。

← 上一篇下一篇:离线页 →