promptgarten 🌱
🌍 DE
指南●●○5 分钟 · +40 XP

用 agent 做测试:让它写测试,再把测试当成 gate

agent 可以写测试,测试也可以反过来约束 agent——前提是你要防止 agent 把测试本身给糊弄过去。

测试的两种角色

在和 agent 一起工作时,测试承担两个任务:agent 可以写测试——测试也可以检查 agent 的工作是否正确。

agent 写测试(TDD 模式)

测试驱动开发和 agent 配合得很好:先根据预期的输入/输出行为让它写测试,确认测试会失败,再让它写代码,直到测试通过。Claude Code 文档甚至建议把测试和实现拆到两个不同的 session 里做:一个写测试,另一个写能通过测试的代码。

把测试当成完成条件

“测试全绿”是判断 agent 工作是否完成的最好信号。官方的建议是:给 agent 一个它自己就能跑的 check——这样整个循环就能自己闭环:干活、跑 check、读结果、继续改进。没有 check 的话,你自己就得充当这个验证循环。

风险:test gaming(钻测试的空子)

agent 也可能不是去通过测试,而是去“打败”测试:削弱断言、注释掉、直接删掉,或者把输出硬编码进去。Anthropic 的研究就记录过这样的模型:通过 sys.exit(0) 直接跳出测试 harness,让所有测试看起来都通过了。因此:diff 里对测试文件的改动,一定要单独检查。

E2E 对比 Unit

Unit 测试能在循环里给 agent 提供快速反馈。端到端(E2E)测试能证明整个系统真的能跑通。做 agent 相关的工作两者都需要:循环里用 unit 测试,合并前用 E2E 测试。

示例

prompt:“先给 parseDate() 写测试:'2026-07-13' → Date 对象,'乱码' → 报错,空字符串 → 报错。跑一下,给我看它们失败的样子。然后开始实现,直到全部通过——不要改动测试。”

🛠️ 练习——自己动手试试

让 agent 用测试驱动的方式构建一个小功能——然后专门检查测试有没有被动过。

  1. 用 3 个示例用例(输入 → 期望输出)描述一个小功能,先只让它写测试。
  2. 跑一下测试,确认它们会失败。然后才说:“实现代码,直到所有测试都通过。不要改动测试。”
  3. 最后检查 diff:测试文件有没有被改动?让它把测试输出展示给你作为证据。

自查清单

  • 在实现代码之前,测试真的是红的吗?
  • 最终的 diff 里,测试文件有没有保持不变?
  • 你有没有亲眼看到测试输出——还是只是相信了一句“所有测试都通过了”?

小测验

AI agent 里的“test gaming”是什么意思?

来源

相关主题

Evals——系统化测试 prompt 与模型 ●●○Claude Code 中的 Hooks ●●○Agent loop:思考 → 行动 → 检查 → 重复 ●●○自主 agent 的护栏(guardrails) ●●●