原文:https://dev.to/robertadam987_/your-ai-coding-agent-says-tests-pass-but-did-it-actually-run-them-4684(作者 @robertadam987_)
AI 编程 Agent 越来越擅长完成任务了。
它们会修改文件。
修复错误。
编写测试。
执行命令。
然后以类似这样的话收尾:
所有测试均已通过
而我们大多数人就直接翻篇了。
但有一个很重要的问题:
Agent 真的运行过它声称通过的测试吗?
这听起来是显而易见的。
其实不然。
因为在 AI 辅助开发中,我们正开始相信总结,而不是证据。
“测试通过”只是一个说法
设想一下 Agent 输出了这样的内容:
实现完成。 ✓ 测试通过 ✓ 构建成功 ✓ 无 lint 错误
看起来让人很安心。
但你仍然不知道:
- 它执行的是什么命令
- 是否运行了完整的测试套件
- 是否有部分测试被跳过了
- 命令是否成功退出
- 输出结果是否来自最新的代码
- 它到底有没有运行过测试
这句话只是一份总结。
它不是证据。
这是一种新型的信任问题
在编程 Agent 出现之前,开发者通常直接运行命令:
npm test
你能看到输出。
能看到失败信息。
也能看到退出码。
而有了 Agent 之后,工作流可能变成:
开发者提出功能需求
↓
Agent 修改代码
↓
Agent 运行了某些东西
↓
Agent 总结执行结果
↓
开发者选择相信总结
现在,在你和真正的验证之间多了一层。
而这一层是可能出错的。
Agent 可能只运行了一部分测试
假设你的项目包含:
单元测试 集成测试 API 测试 端到端测试
Agent 运行了:
npm run test:unit
全部通过。
然后它汇报:
所有测试均已通过。
严格来说,确实有一些测试通过了。
但整个应用从未被完整验证过。
这个区别很关键。
它汇报的可能是过期结果
另一种很容易出现的失败模式:
Agent 运行测试
↓
测试通过
↓
Agent 又修改了代码
↓
Agent 汇报"测试通过"
这句话在当时是真的。
但现在可能已经不是了。
验证应该针对代码的最终状态来进行。
测试通过,仍可能意味着测试本身是错的
还有另一个问题。
AI 写完了功能。
接着 AI 写测试。
然后 AI 运行这些测试。
全部通过。
很好。
但问题在于:实现代码和测试代码可能共享着同一个误解。
比如:
对需求理解错了
↓
AI 写出代码
↓
AI 按同样的理解写测试
↓
测试通过
一片绿。
功能却仍然是错的。
所以真正的问题其实有两个:
测试真的运行过吗?
以及
它们本身是正确的测试吗?
两个都重要。
要证据,不要自信
我现在越来越倾向一条简单的规则:
如果 agent 声称完成了验证,就要求它出示背后的证据。
与其直接接受一句:
测试通过。
不如要求它给出:
给我看: 1. 你运行的确切命令 2. 退出码 3. 一共运行了多少个测试 4. 多少个失败 5. 多少个被跳过 6. 是否是在最后一次代码修改之后运行的
这样一来,声明就变得可查验了。
给你的 agent 一份“验证契约”
你可以把这件事写进日常的编码 agent 指令里。
例如:
永远不要说“测试通过”,除非你确实运行了相关的测试命令。 报告验证结果时,必须包含: - 确切运行的命令 - 退出码 - 测试总数 - 失败数 - 跳过数 - 构建状态 - lint/typecheck 状态 如果某项没有执行,就说“未验证”。
最后这一句尤其重要:
没验证过的,就直说没验证。
“我没有运行集成测试”这句话,远比虚假的自信有用。
把实现和验证分开
对于重要的改动,不要让同一个工作流既负责产出结果,又负责给自己的结果盖章认证。
更强的模式是这样的:
agent 实现功能
↓
独立运行的测试命令
↓
CI 验证
↓
人工审查结果
对于风险更高的改动,还可以更进一步:
Agent A → 负责实现 Agent B → 对抗性审查 CI → 测试/构建/安全检查 人工 → 最终批准
关键在于独立性。
生成代码的那套系统,不应该成为你相信代码正确性的唯一来源。
CI 才是唯一事实来源
agent 发来的消息只能当作有用的背景参考。
而不是最终权威。
比如:
agent 说:
所有测试都通过了。
CI 说:
3 个集成测试失败了。
相信 CI。
这就是为什么即使 AI 写的代码越来越多,传统工程体系依然重要。
你仍然需要:
- CI
- 确定性测试
- 构建检查
- 类型检查
- lint 检查
- 安全扫描
- 部署门禁
AI 不会取代这些体系。
反而会让它们变得更重要。
小心“已修复”这种说法
同样的原则也适用于 agent 的其他声明。
比如:
“这个 bug 已经修复了。”
是怎么验证的?
“构建没问题。”
运行的是哪条构建命令?
“没有破坏性变更(breaking changes)。”
做过哪些兼容性检查?
“这次迁移是安全的。”
有没有在贴近真实的数据上测过?
“这是安全的。”
实际运行过哪些安全检查?
AI agent 的语气可以显得无比笃定。
但笃定不是证据。
一份更好的完成报告
与其这样:
完成了。 一切正常,所有测试通过。
我更希望看到这样:
功能实现完成。 已执行的验证: npm test Exit code: 0 128 个测试通过 0 个失败 3 个跳过 npm run typecheck Exit code: 0 npm run lint Exit code: 0 集成测试未运行。 浏览器手动测试未执行。
这样的报告有用得多。
我清楚地知道哪些被验证过了。
哪些没有。
把“未验证”加进你的词汇表
AI 辅助开发最缺的一句话就是:
未验证。
agent 说下面这些话完全没有任何问题:
已实现,但未测试。
或者:
单元测试通过,集成测试未运行。
或者:
我无法验证这一点,因为所需的服务不可用。
这些回答都好过假装笃定。
好的工程实践不在于听起来自信。
而在于清楚自己手上到底有哪些证据。
我的一条简单规则
对于任何重要的 AI 生成改动:
永远不要轻信这句:
“能跑。”
而要认这句:
“这是我的验证过程。”
这一点差别,就能挡掉大量的虚假自信。
一份实用检查清单
在接受 agent 的“测试通过”消息之前,先问:
执行的是什么命令?
你应该知道确切的那条命令。
运行的是完整的相关测试套件吗?
而不是只跑了其中一个子集。
退出码是多少?
成功与否应当是可度量的。
有没有被跳过的测试?
被跳过的测试同样重要。
验证是在最后一次代码修改之后运行的吗?
而不是在最后一次编辑之前。
CI 确认过结果吗?
优先采用独立的验证。
我能查看输出吗?
证据应该随时可以调取。
写在最后
AI 编程 agent 生成代码的能力越来越强。
但随着它们越来越自主,开发者需要对一件事更加上心:
验证。
危险的工作流是这样的:
AI 写代码 ↓ AI 说能跑 ↓ 人信了 ↓ 合并
更好的工作流是这样的:
AI 写代码 ↓ AI 出示证据 ↓ 运行独立检查 ↓ 人工验证 ↓ 合并
因为:
“测试通过”这句话,并不是测试确实通过的证明。
它只是一个声明。
而在软件工程里,重要的声明都应该拿得出凭证。
原文:https://dev.to/robertadam987_/your-ai-coding-agent-says-tests-pass-but-did-it-actually-run-them-4684(作者 @robertadam987_)



