AI 用于测试生成:它的助力与误区
AI 写测试很快。但它也会写出看起来很真实、实则验证了错误内容的测试。
你把一个函数粘贴到 AI 中。三十秒后,你得到了十二个通过的测试。你的覆盖率分数上升了。你觉得自己效率很高。
然后,生产环境出现了一个 Bug。你查看那十二个测试,发现它们没有一个能捕捉到这个 Bug。
AI 测试的是你的代码“做了什么”,而不是你的代码“应该做什么”。
AI 很有用,但你必须知道如何正确使用它。
AI 的优势所在:
- 生成样板代码(boilerplate),例如 setup 和 teardown 块。
- 编写重复的工厂助手(factory helpers)和数据对象。
- 基于单一优秀的测试模式创建多种变体。
- 处理明显的边界情况,如
null、空字符串或零。
AI 的局限所在:
- 基于实现的测试:它编写的测试遵循代码结构而非业务逻辑。如果你重构代码,即使结果仍然正确,测试也会失败。
- 浅层的边界情况:它能发现明显的错误,但会错过特定领域的 Bug。它不了解你的时区特性、数据库约束或特定的业务规则。
- 脆弱的 Mock:它会 Mock 那些本应保持真实的内部服务。这使得测试难以维护,并且在重构时极易损坏。
如何使用 AI 而不制造“测试演戏 (test theater)”:
- 首先定义契约。用简单的自然语言写一句话,说明测试必须证明的内容。例如:“过期代码必须返回原始金额。”
- 将这句话交给 AI。让 AI 编写代码,但你必须掌控其意图。
- 仅在边界处进行 Mock。内部模块使用真实实例。只对外部 API 或数据库进行 Mock。
- 手写一个领域相关的边界情况。AI 处理“显而易见”的边界,而你必须处理那些真正会导致生产事故的“凌晨三点”级别的边界情况。
不要让 AI 来决定测试验证的内容。利用它来编写代码,但逻辑必须由你提供。
来源:https://dev.to/nazar_boyko/ai-for-test-generation-where-it-helps-and-where-it-lies-jhm
