AI 协作工程化 06:测试不是聊天结论,冻结验收契约与可复跑证据
“我已经测过了”在协作系统里几乎没有信息量。它没有说明测了什么版本、覆盖了哪些需求、输入数据从哪里来、失败后留下了什么证据。对于 AI 参与的测试,这个问题更突出:模型可以根据当前上下文临时编造一个场景,却无法保证下次会得到相同范围。
更可靠的思路是先把验收要求编译成冻结测试契约,再执行环境调用。测试报告记录的是当时版本的事实,不承担改变流程状态的职责。
从自然语言到原子声明
测试不能直接从“需求标题”猜测接口路径或页面路由。它应从正式需求中的验收口径、计划中的验证点和开发记录中的完成证据提取原子声明。
需求点验收口径 -> AC-RP-003-1, AC-RP-003-2
任务验证点 -> VP-TASK-011-1
↓
场景矩阵
↓
可执行 case每一条原子声明要么被恰好一个测试场景覆盖,要么被明确记录为输入缺口。这个“一对一或显式缺口”的规则很重要:它阻止测试工具悄悄跳过自己无法理解的需求。
| 输入层 | 典型内容 | 测试系统的职责 |
|---|---|---|
| 需求 | 用户可观察的效果与边界 | 提取验收声明 |
| 计划 | 验证点、异常与回滚口径 | 补足验证声明 |
| 开发记录 | 已执行的范围与稳定锚点 | 关联可复核证据 |
| 环境配置 | API、页面与受控凭据 | 只在执行时读取,不写入报告 |
冻结快照是测试前提
生成 suite 后,应同时冻结 Handoff、需求、计划和开发记录的内容摘要,例如 SHA-256。执行前先校验 suite 结构、声明覆盖、引用、变量和 DSL,再复核源文件快照仍然一致。
快照不让测试“更聪明”,但让它诚实:如果需求或实现已经变化,旧 suite 不能假装仍然代表当前状态。它应该停止环境调用,报告为结论不充分,并要求重新发现或重新冻结。
执行隔离与证据边界
一个测试 case 应拥有独立变量作用域;UI case 使用独立浏览器上下文;准备数据、执行步骤和清理动作都只属于当前 case。这样可以避免前一个场景残留的数据让后一个场景“碰巧通过”。
测试证据同样需要边界。报告可以保留脱敏后的截图、日志片段或响应投影,但不能把 Cookie、连接串或完整敏感响应写进 suite、报告或命令行。无法安全脱敏时,正确行为是记录“未保留”,而不是为了完整性泄漏环境信息。
测试结果不等于流程状态
测试 Runner 可以输出 passed、failed、blocked、error、skipped 等测试事实,并归纳为 passed、failed 或 inconclusive 的整体结论。但它不应直接把需求工作流改成完成或失败。
这是刻意的分层:
- 测试 Runner 负责“在冻结契约下实际观察到什么”。
- Accept Reviewer 负责“这些事实是否足以支持需求目标达成”。
- Controller 负责“根据合法验收 Return 是否结束流程”。
如果 Runner 直接改状态,就会把一个环境执行工具变成需求裁决者;如果验收完全忽略 Runner,又会让测试证据沦为装饰。正确关系是引用与评估,而非越权写入。
不要把 blocked 伪装成缺口
测试系统通常有两类未完成:
- 输入缺口:无法从正式事实确定场景的入口、预期或规则。
- 执行阻塞:场景已经确定,但当前环境缺少明确技术前提,例如不可用的适配器或受控环境。
二者不能混用。前者需要回到需求、计划或数据准备;后者表示一条已确定 case 暂时无法运行。区分它们,才能防止团队把测试设计不完整误报为“环境问题”。
小结
冻结验收契约把测试从临时行为变成可复跑的事实生产过程:来源明确、场景可追溯、执行有前置校验、报告不可覆盖。它不替代验收判断,却让验收判断拥有更可靠的证据基础。
下一篇讨论另一条常被混淆的链路:项目知识库、正式设计和面向人的宣讲材料,为什么必须有不同的读写边界。
系列导航:
