AI 写完了,也说修好了:测试人员如何验收编码 Agent?
代码改了、测试绿了、Agent 也说修好了,为什么仍然不能直接验收?从一个系统实现案例出发,把修复声明拆成原始失败样本、系统不变量、真实操作和可复查证据,建立编码 Agent 的交付验收流程。
“已经修复,并发处理已加入,验证通过。”如果验收记录只有这句话,你还不知道最重要的一件事:最初那个出问题的场景,现在到底怎么样了?
编码 Agent 能连续修改多个文件、补测试、执行命令,最后给出一份条理清楚的完成报告。这让开发交付变快,也让测试人员面对一种更容易混淆的状态:报告已经完整,证据却可能没有闭合。
“改过代码”“某个测试通过”“原问题已消失”,是三个不同的判断。它们需要不同的证据,不能被一句“已验证”合并。
上一篇《别再迷信 LLM 裁判》讨论的是如何判断 AI 问答是否正确。这篇把对象换成编码 Agent:当它实际改动系统时,我们怎样确认功能成立、原缺陷被修复,而且没有留下新的副作用?
一、一个没有回到原现场的修复
2026 年 9 月的论文 When Agents Implement Systems记录了一次编码 Agent 按既定规格实现多组件系统的过程。作者发现,一个 18 段文档的处理耗时达到 242 秒;Agent 加入并发后,仅用更小的文档验证,没有重新测量原始慢样本,却报告修复有效。
论文还记录了配置路径、重复写入、图关系一致性和缩放渲染等问题。它们提醒我们:静态检查之外,还存在只有换入口、重复执行或实际渲染才暴露的约束。
这是单 Agent、单次会话的观察性案例,不能据此推断所有编码 Agent 的缺陷频率。本文也没有复现其系统。下文是从该案例出发提出的工程验收方法,示例数据和门槛均用于演示,不是论文实验结果。
这个案例值得注意的地方,是验收对象被悄悄换掉了。原来的问题是“特定输入处理过慢”,后来的证据却是“新实现能处理另一个更小的输入”。后者有价值,但不足以关闭前者。
合理的代码解释,可以支持我们继续测试。只有与原问题对应的观察结果,才能支持“修好了”。
二、先把“完成”拆成可验证的声明
假设需求是:“支持批量导入文档,重复提交不新增副本,失败后能继续处理。”Agent 交付了接口、队列任务、数据库代码和进度页面。
我们可以把验收拆成五类。它们不是必须机械执行的五套测试,而是检查这次改动有没有遗漏重要证据。
| 验收对象 | 要回答的问题 | 应当留下的证据 |
|---|---|---|
| 构建与静态约束 | 代码能否编译,类型和基本规则是否满足? | 命令、退出码、失败与警告摘要 |
| 功能契约 | 指定输入是否产生约定结果? | 输入样本、预期、实际输出 |
| 状态与系统不变量 | 重复、重试、失败后,数据关系是否仍成立? | 前后状态、数量、关联和唯一性断言 |
| 真实使用路径 | 用户实际操作能否完成任务? | 操作记录、可检查的产物、必要截图 |
| 原缺陷与影响范围 | 原始问题是否消失,相邻行为是否退化? | 原样本重跑、对照测量、针对性回归 |
构建通过,可以证明一部分静态约束成立。它不能证明重复导入没有副本,也不能证明页面显示“完成”时导出文件真的有内容。
验收时可以逐句检查 Agent 的报告。例如“配置问题已修复”太宽泛,应改写为:“从仓库根目录和约定的任务启动目录运行,都能定位同一个配置文件。”这句话有入口、有预期,也能被实际结果推翻。
好的验收条件,不只方便宣布通过,也让失败有明确的位置。
三、把业务要求写成系统始终要满足的条件
很多测试只检查一次调用的返回值。系统问题常出现在多次执行、多个对象或者多个入口之间。
“不变量”这个词听起来抽象,实际含义很简单:无论经过哪条允许的路径,有些关系都必须成立。
1. 重复提交后,什么应该保持不变?
如果需求规定重复导入同一版本文档不产生副本,就不能只断言第二次请求成功。还要比较第一次和第二次完成后的状态:文档数量、片段数量、稳定标识及关联关系是否符合约定。
这不代表所有重复执行都应返回完全相同的结果。更新时间可以变化,审计记录也可以新增。验收前应区分业务数据和执行记录,明确哪些字段允许变化。
测试至少可以包含三个场景:正常重复提交、同一请求因超时重试、处理到一半失败后重试。它们分别覆盖重复调用、结果不确定和部分完成,不能用一个“执行两次”代替全部。
2. 返回的对象之间,关系是否完整?
假设接口返回图的节点和边,那么每条边的两个端点都应该出现在允许引用的节点集合中。仅仅验证“返回了三条边”,可能完全漏掉悬空引用。
同样的方法可以用在订单明细与订单、附件与文档、任务结果与任务记录上。测试不应只分别检查每个列表非空,还要检查它们之间的关系。
当类似数据经由详情接口、搜索接口和导出接口返回时,应检查这条约束是否在相关入口中一致成立。是否共享代码是实现选择,是否共享业务规则是验收要求。
3. 换一个入口,系统是否还是同一个系统?
开发者从项目根目录运行正常,不代表定时任务或后台进程也正常。配置路径、文件路径和数据库选择,可能受到启动目录影响。
测试人员不需要穷举机器上的所有目录,而应列出产品实际支持的入口:Web 服务、队列 worker、命令行或计划任务。确认它们在测试环境中加载预期配置、访问预期数据,并且缺失配置时明确失败。
“自动退回默认配置后还能运行”不一定算成功。如果退回导致连接到错误环境,正常退出反而掩盖了更严重的问题。
四、修复验收必须保留原始失败样本
缺陷被发现时,最有价值的资产往往不是错误截图,而是能够再次触发它的输入和环境说明。
我建议给每个需要回归的缺陷保存一张简短记录卡:
| 字段 | 示例:批量导入耗时过长 |
|---|---|
| 缺陷编号 | IMPORT-017 |
| 原始样本 | 固定的测试文档及文件哈希 |
| 版本与入口 | 提交标识、批量导入入口 |
| 初始状态 | 独立测试库,样本尚未导入 |
| 原始现象 | 端到端耗时超出已约定门槛 |
| 正确性条件 | 所有片段处理完整,没有重复记录 |
| 性能门槛 | 在约定环境与负载下满足业务目标 |
| 修复后证据 | 同一案例的结果、耗时及日志位置 |
其中的门槛应在看见修复结果之前确定。否则,修复用了多久,我们就把“可接受”改成多久,测试就失去了判定作用。
对于性能修复,前后比较还应记录硬件、服务版本、并发参数、缓存状态和外部接口条件。输入相同但后一次命中了缓存,不能直接把差异归功于并发改造。
可以先在可控环境中隔离外部服务波动,再补一次真实依赖下的验证;两种证据应分别标注。少量重复测量有助于观察波动,但只有几次运行时,不应包装成可信的 p95 或容量结论。
重跑原样本之后,再补一个有针对性的邻近场景。例如从串行改成并发,需要额外关注限流、失败重试、结果顺序和重复写入。快了但漏处理一部分数据,不能算性能修复通过。
如果原样本无法获得,就明确记录“替代样本验证通过,原问题尚未直接复验”,并由负责人判断这份证据是否足以接受。不要把替代验证改写成原问题已经关闭。
五、一个可以照着做的导入验收示例
下面是一套假设的文档导入需求,用来说明如何组织验证,并非已经执行过的实测报告。
约定:固定测试文档含 12 个片段;同版本重复提交不得新增业务副本;一次失败可以重试;导出文件必须包含全部片段。12 只是示例规模,不是通用验收标准。
第一步:先固定结果,再让 Agent 修改
准备无敏感信息的测试文档,把每个片段编号。记录首次导入后应出现的一份文档、12 个片段以及完整关联。把测试库和样本标识固定下来。
性能门槛单独依据业务目标约定,不从 Agent 改完后的结果倒推。外部模型调用若不可避免,也应固定模型版本和关键参数,记录实际返回的差异。
第二步:按状态变化组织用例
| 场景 | 操作 | 核心预期 |
|---|---|---|
| 首次处理 | 从真实入口提交文档 | 片段全部完成,界面状态与后台结果一致 |
| 重复处理 | 再提交同一版本 | 不增加业务副本,允许约定的执行记录新增 |
| 中途失败 | 在测试环境注入一次依赖错误 | 失败可见,不把部分完成显示成全部成功 |
| 失败重试 | 恢复依赖后重新执行 | 最终结果完整,已完成部分不重复累加 |
| 导出检查 | 点击导出并打开产物 | 内容覆盖全部片段,编号可核对 |
故障注入应在独立测试环境进行。对于已有正式数据的环境,应使用明确隔离的测试租户或测试记录,不以清空数据库作为方便的准备步骤。
第三步:从用户入口走到最终产物
接口测试通过之后,实际操作上传、查看进度、重试和导出。检查按钮是否可用、错误信息能否帮助继续操作、重复点击会不会触发额外任务。
尤其要打开导出文件。HTTP 200、下载完成和文件存在,都不能证明内容正确。若产物是 DOCX 或 PDF,抽查文本之外还应渲染检查;若是 JSON,应检查字段、记录数和引用关系。
截图用于说明页面状态,断言用于判定业务条件。两者可以配合,但不要用“截图看着正常”代替对数据的核对。
第四步:给出能追溯的结论
验收报告应区分通过、失败、未执行和阻塞。比如下面这段只是报告格式示例:
原始重复导入场景已在提交 ABC123 上复验,业务记录数量符合预期。失败重试和导出内容检查通过。性能测试因外部依赖不可用而阻塞,暂不关闭性能缺陷。证据目录关联本次运行编号。
这样的报告没有“全部完成”悦耳,但下一位接手的人知道还缺什么,也不会把功能通过误认为性能目标已经达成。
六、让 Agent 写测试,但别让它自行定义通过
让同一个 Agent 实现功能、补充测试、执行检查,可以节省大量重复工作。问题在于,如果预期也完全由它根据当前实现生成,测试可能只是确认代码按照自己的写法运行。
测试人员需要独立控制三样东西:业务预期、必须保留的失败样本、发布门槛。Agent 可以帮助完善用例,但不能为了变绿而静默删除失败断言、缩小输入规模或替换不方便的样本。
下面这段可以作为任务中的验收要求,再按实际项目调整:
修改前列出本次需求的可观察结果、禁止出现的副作用和原始失败场景。修复后先重跑原场景,再检查受影响的相邻路径。每项结论写明版本、输入、预期、实际结果和证据位置。未运行、运行失败和被环境阻塞分别标注。不得通过删除断言、放宽门槛或替换原样本来宣告通过;确需调整时,说明原因并交由负责人判断。
这段要求的重点是结果可复查,不是索取 Agent 的内部推理。我们需要知道它运行了什么、观察到了什么,以及这些观察支持哪一个结论。
对于关键缺陷,可以检查新增回归用例是否在修复前版本失败、在修复后版本通过。前提是环境和样本可控、执行安全。若用例在两个版本都通过,就要调查它是否真的覆盖了原问题。
也不必为每一处文案修改建立复杂验证。验收成本应随风险变化:静态内容侧重构建、链接和阅读效果;导入写入侧重状态与恢复;性能修改侧重可比测量;涉及权限或资金的行为则需要更严格的独立审查。
七、上线前,用这六个问题收口
- 预期是否独立于实现? 需求和验收条件没有随着当前结果悄悄变化。
- 原始失败场景是否复验? 输入、入口、版本和环境差异有记录。
- 状态是否正确? 重复、失败和重试没有留下不允许的数据变化。
- 真实路径是否走通? 用户完成了操作,最终产物也经过检查。
- 影响范围是否覆盖? 根据修改机制选择回归场景,没有用大量无关测试掩盖空白。
- 结论是否对应证据? 未执行和阻塞项明确,风险接受有负责人。
有关键项失败,就继续修复;证据缺失,就把状态保留为待验证。低风险剩余项可以按团队流程接受,但接受的是明确的风险,不是一个含糊的“应该没问题”。
测试人员在编码 Agent 工作流中的价值,是把自然语言需求变成能观察、能判错、能追溯的条件。Agent 可以承担越来越多的执行工作,验收仍然需要有人守住结论与证据之间的对应关系。
当它再次说“已经修好了”,我们可以把注意力落到一个具体问题上:原来失败的那一次,现在用什么结果证明它已经通过?
参考资料与延伸阅读
- When Agents Implement Systems: A Case Study in Defects, Detection, and Evaluation Rigor(论文全文,v1):本文案例来源,重点参见缺陷记录及 Discussion 中的修复复验缺口。
- 论文摘要与版本记录:单次观察性案例,不用于推导行业缺陷率;本文未复现实验。
- 别再迷信 LLM 裁判:做 AI 问答评测,为什么必须先知道正确答案?:从问答预期与评分证据理解验收基础。
- GUI Agent 的原子性测试:进一步关注任务失败后的状态与副作用。
- AI 代码编辑中的安全漂移:功能修复之外,还要检查安全属性是否变化。
版权与声明
本站所有内容仅代表作者个人观点,与作者供职的公司、客户或其他关联机构无关。
本文除特别声明外,采用 CC BY-NC-SA 4.0 许可协议。转载或改编请署名、附原文与许可证链接,并标明改动;不得用于商业用途,演绎作品须以相同许可发布。
评论