
Claude Code 很乐意帮你写测试,也很乐意告诉你测试通过了。这两个声明之间隔着一道沟——大多数 QA 自动化配置,就是在这道沟里悄悄死掉的。
这篇文章聊聊怎么把 Claude Code 塞进一个真正管用的 QA 循环:它什么时候可以放手跑,你会踩到哪三个坑,以及怎么把它们堵上。
标准的做法是让 Claude Code 生成一套测试用例。很快,输出看起来也没毛病。问题出在结构上:写代码的模型和给代码打分的模型是同一个。
Claude 同时写了功能和这个功能的测试,测试里编码的就是它自己对这个功能的理解。如果理解本身就是错的,测试也会错在同一个方向,然后通过。你验证的不是行为,是内部一致性。
这不算模型的锅。让一个人自己写了个函数,再凭记忆写测试,同样有这个盲点。区别在于人通常会打开应用点一下。
用对了的话,它在这些地方很强:
把需求转成测试用例让你review。 先用大白话把用例列表要过来,在任何代码之前。边界 case 漏了就漏了,在最便宜的阶段抓出来。
写机械的部分。 Fixture、工厂类、setup 和 teardown、你已经审过的用例的参数化版本。
解释失败。 贴个堆栈跟踪,它通常比你更快找到根因。
重构时维护测试。 改名、改签名这类脏活累活,正好该自动化。
这些场景都不需要它评判自己的工作质量。
最常见的一个。Claude 说"修好了,测过了",实际上是改了个文件,什么都没跑,或者跑的用例根本没覆盖这次改动。用户已经把这个坑踩烂了:代码不完整、实现没测试、占位符还在、结论倒是很自信。
解法是结构性的,不是换个 prompt。 在前面就定义好验证命令,让命令成为事实来源,而不是它的总结。
在你告诉我任何东西搞定之前,先跑这个: npm run build && npm test 把实际输出贴过来。如果失败了继续搞,不要自己总结。 让 agent 去验证下单流程,它会去找成功提示文字。这是截图工具也能干的事,也恰恰是漏掉那些贵得要命 bug 的检查方式:
POST /api/order 返回了 500。每一种都显示绿色通过。DOM 不是程序,一个视觉断言通过了说明不了底下发生了什么。
LLM 重跑一遍浏览器流程,本质上是不确定的。跑三次可能得到三个结果。一旦测试开始 flaky,人就不看了,不看的测试套件比没有还糟糕——因为还在烧钱跑。
给它验收标准,而不是目标。 "让下单流程能用"没法验证。"已登录用户加一件商品可以完成下单;订单写入 DB;卡片只扣一次款"是一张清单。
在分支或 worktree 上跑。 给 agent 犯错的空间,别让它搞砸了还得你手动回滚。
作者和裁判要分开。 打分的不该是干活的那个。裁判可以是人、可以是没上下文信息的第二个 agent、也可以是直接读运行中应用的外围观察者。
断言程序真相,不是像素。 能抓住上面那些 bug 的检查项不是"成功文字在不在",而是:
让检查足够便宜,能每次都跑。 一次验证要一块钱加九十秒,就会被跳过。一次花不到一分钱、一秒跑完,就会变成习惯。
Reticle 就是上面说的那个外围裁判。它是一个免费开源的 SDK,跑在你开发环境里的应用里。你的 agent 问它要证据;它打开运行中的应用,跑一遍流程,读取网络调用、内部状态、console 和 React 提交,然后返回通过或失败,以及出错的文件和行号。
因为它读的是程序而不是截图,所以能抓到那些静默的 bug:干净页面背后的 500、UI 和 store 不一致、重复扣款。因为它重放录制的流程而不是让模型重跑,同一个输入每次都给出同样的判定,一次 suite 大概只花 47 个 token。
重点不是不用 Claude Code 做 QA。是不再让它同时当作者和裁判。
npx @reticlehq/server init 然后告诉你的 agent,报告任何东西完成之前先用 Reticle 验证。它会开始抓自己的错——这是 QA 自动化在 agent 写得比你看得还快的时代,唯一能活下来的版本。
这些都不替代发布门禁。Playwright 和手写的端到端测试还是卡着发布:跑在 CI 里、覆盖你支持的浏览器、抓 Reticle 故意不抓的像素回归。Reticle 卡的是编辑,在循环里,在 agent 还在干活的时候。
做对的团队通常两个都跑,而且清楚哪个回答哪个问题。