【AI Native开发-14】Verify:从“测试通过”到“需求被证明”
摘要
所有命令变绿,依然不代表产品正确。Verify 是 SDD 四道闸门的最后一道,它要回答的不是”测试过了吗”,而是”Spec 里的每条需求,是否都有证据证明被满足了”。
核心论点:
- 测试通过是手段,需求被证明是目的。 一个功能可能所有测试都绿,但漏测了某条需求、或测试本身是陪跑、或存在根本没被任何用例覆盖的行为。Verify 把视角从”测试”抬升到”需求”。
- 证据要按需求归集,而不是按测试归集。 需求追踪矩阵在这里闭合:REQ → 文本用例 → 自动化用例 → 执行结果 → 证据。每条 REQ 都要能指着一份具体证据说”它被验证了”。
- 诚实标注边界,比假装全绿更重要。 总有”已验证 / 未验证 / 无法自动化验证”的部分。Verify 报告的可信度,恰恰体现在它敢不敢写明”什么没测、为什么、风险多大”。
本篇给出 Verify 的证据类型、追踪矩阵闭合方法、证据充分性判据、人工验收清单、已知限制标注,以及 Verify 报告模板和准出标准。
一个典型场景
删除功能全量回归跑完:类型检查过、单元过、接口过、构建过、E2E 过。AI 报告:“所有测试通过,功能完成。”
发布前你按 Verify 的思路核对,发现:
- REQ-006”删除失败时列表保持原状态并提示错误”——翻遍测试,没有一条用例覆盖失败提示的界面表现,接口层只测了返回码;
- REQ-005 里”删除后刷新页面文章仍不可见”——自动化测了接口返回 404,但没测静态站重新构建后列表真的少了这篇(dev 模式下文件删了但列表可能还是旧的);
- “二次确认弹窗”的交互——只有 E2E 测了”取消不发请求”,“确认后真的删除”这条主路径在界面层没人点过;
- 删除操作没有任何审计日志——而这是 Spec 评审时没人提、测试也无从覆盖的业务空白。
每一条测试都是绿的。但如果发布标准是”每条需求都被证明”,这份功能还不能发——因为有需求没被证据覆盖,还有需求在真实环境(构建后)的行为没被验证。
这就是 Verify 存在的意义:它不看测试绿不绿,它看需求有没有被证据闭环。
核心问题:测试通过 ≠ 需求被满足
下文的 API/E2E 执行结果是用于说明 Verify 结构的假想案例,不是本博客当前仓库的真实执行记录;本仓库目前可核验的主要构建命令是
pnpm build。
“测试通过”和”需求被证明”之间,隔着四种 gap:
gap 1:覆盖缺口——某条 REQ 根本没有对应用例
(REQ-006 的失败提示没人测)
gap 2:层级缺口——测了但没在能验证它的层级测
(接口测了 404,但"构建后列表消失"是静态站行为,接口层测不到)
gap 3:环境缺口——在 dev/测试环境过了,生产形态没验证
(dev 绿,构建后/部署后行为未验证)
gap 4:有效性缺口——有测试但测试是陪跑
(空实现也能过的断言,等于没测)全绿的测试报告对这四种 gap 全部无感。Verify 的工作就是逐条 REQ 去查:有没有证据、证据在哪一层、在什么环境、证据是否有效。Verify 的单位是需求,不是测试。
Verify 要汇总哪些证据
Verify 不是再跑一遍测试,而是把各阶段产出的证据,按需求归集、核对、下结论。证据来源:
1. 静态证据(命令按项目实际 scripts 替换)
- 类型检查通过(如 astro check / tsc)
- lint 通过
- 生产构建通过(本项目即 pnpm build)—— 静态站尤其关键
2. 自动化证据
- 单元测试结果(纯逻辑)
- 接口/集成测试结果(真实中间件、真实文件操作)
- E2E 测试结果(真实浏览器路径)
- 每条结果关联 TEST 编号,可回溯 REQ
3. 人工验收证据
- 关键用户路径由真人在【类生产环境】操作一遍
- 视觉/交互/文案这类无法自动化判定的项
- 异常路径的人工确认(断网、权限不足时的表现)
4. 变更证据
- Diff 在 Plan 授权范围内(第 09 篇变更控制结论)
- 无越界文件、无幻觉依赖、无调试残留
5. 追踪证据
- 需求追踪矩阵完整闭合(下一节)注意人工验收不可省略。有些东西自动化天然测不了或测不真:弹窗交互的真实手感、错误提示是否清晰、删除后页面在真实构建产物里的表现。这些必须真人在尽可能接近生产的环境(最好是预览部署)走一遍。
需求追踪矩阵:在这里闭合
第 10 篇建立了 REQ → TEST 的矩阵,Verify 把它一路延伸到证据:
REQ 需求摘要 文本用例 自动化用例 执行结果 证据/结论
REQ-001 管理员删未公开文章 TEST-002-1 api/delete E2E 通过 接口404 + E2E确认路径 ✓
REQ-002 仅管理员可删 TEST-002-1~5 api/delete 通过 403且文件仍在 ✓
REQ-003 已公开文章不可删 TEST-003-1/2 api/delete 通过 409且文件仍在 ✓
REQ-004 取消确认不删除 TEST-004-1 e2e/cancel 通过 监听到无DELETE请求 ✓
REQ-005 删除后重建仍不存在 人工构建验收 build/preview 部分 构建产物尚未人工确认 ✗
REQ-006 失败时保持列表状态 TEST-006-1/2 (仅接口返回码) 部分 界面失败提示【未验证】✗
REQ-007 目标不存在/重复删除 TEST-007-1/2 api/delete 通过 返回 404 且无额外副作用 ✓逐行核对三个问题:
- 每行都有证据吗? REQ-006 这一行,自动化只到接口返回码,界面失败提示没有证据 → 标记为未闭合;
- 证据在正确的层级和环境吗? REQ-005“删除后重建仍不存在”需要在构建产物上验证 → dev 层的证据不够;
- 证据有效吗? 抽查关键用例做过空实现测试(第 11 篇),确认不是陪跑。
矩阵里任何一行出现”无证据 / 部分 / 未验证”,这条需求就没有被证明,Verify 不能给它打勾。 这张表是 Verify 的核心交付物,它把”我觉得测过了”变成”REQ-006 缺一条界面失败提示的证据”。
证据充分性判据
对每条已闭合的 REQ,还要判断证据是否”充分”,而不只是”有”。判据:
充分的证据:
✓ 验证了行为和副作用(不只状态码,还验证数据状态)
✓ 在能真实复现该行为的层级(静态站行为在构建产物上验)
✓ 权限/异常用例验证了"没造成破坏"
✓ 关键用例通过空实现测试,证明断言有效
✓ 结果可复现(不是偶发、不是重试压绿)
不充分的证据(即便测试是绿的):
✗ 只断言"没报错""函数被调用"
✗ 关键依赖被 mock 掉(如权限中间件被 mock)
✗ 只在 dev 验证了生产形态才有的行为
✗ 靠重试通过的 flaky 用例
✗ 断言与 Spec 措辞对不上(测的不是需求要的)人工验收清单
自动化之外,真人在预览/类生产环境走一遍,重点放在自动化够不着的地方:
【主路径(真人操作)】
□ 管理员登录,删一篇草稿(未公开,hide: true):确认弹窗 → 确认 → 文章消失
□ 刷新页面 / 重新构建后,文章确实不在列表
□ 删除后直接访问该文章 URL,行为符合预期(404 或跳转)
【异常与权限(真人确认表现)】
□ 普通用户看不到删除入口;即使看到,操作也被拒
□ 删除失败(如断网、权限失效)时:列表不乱、有清晰提示、
数据没丢
□ 已发布文章无删除入口 / 操作被明确拒绝并说明原因
【界面与副作用】
□ 二次确认弹窗文案清晰、取消和确认按钮行为正确
□ 删除后列表、标签、搜索结果、相关图片资源的表现符合预期
□ (如 Spec 要求)删除操作有审计记录 / 日志
【环境差异】
□ 在【生产构建产物】或预览部署上验证,而非只在 dev 模式
□ 本地与部署环境行为一致人工验收发现的任何”Spec 没规定但不合理”的现象(比如删除后图片成了孤儿文件),都是需求空白,要回流 Spec,而不是当场拍一个处理方式。
诚实标注:已验证 / 未验证 / 无法验证
一份可信的 Verify 报告,必须显式区分三类,而不是给一个笼统的”通过”:
【已验证(Verified)】
有充分证据证明满足 Spec。列出 REQ + 证据。
【未验证(Not verified)】
应该测但还没测 / 证据不足。说明缺什么、风险多大、
补验证的计划。这部分不闭合就不能发布(除非风险被接受)。
【无法自动化验证(Manual / Cannot automate)】
明确标注为人工项,说明为什么自动化不适用
(纯视觉、主观体验、第三方环境依赖),
并给出人工验证的结论和验证人。
【已知限制(Known limitations)】
本次明确不覆盖的范围,以及环境差异
(如"未在 IE 验证""高并发删除未压测")。诚实标注未验证项,不是报告的污点,而是报告可信的来源。一份写着”全部通过、无任何限制”的 Verify 报告反而最不可信——真实系统一定有边界。敢写清楚”什么没测、风险多大”,决策者才能做出知情的发布决定。
Verify 报告模板
# Verify Report: <功能名>
## 结论
- [ ] 所有 P0 需求已验证,准予发布
- [ ] 存在未闭合项,不准予发布(见下)
## 需求追踪矩阵(闭合状态)
| REQ | 摘要 | 文本用例 | 自动化 | 结果 | 证据 | 状态 |
|-----|------|---------|--------|------|------|------|
| ... | ... | ... | ... | ... | ... | ✓/✗/部分 |
## 静态证据
- 类型检查:通过 / 失败
- lint:通过 / 失败
- 生产构建:通过 / 失败(静态站必查)
## 自动化执行摘要
- 冒烟:x/x 通过
- 受影响:x/x 通过,失败/跳过明细
- 全量回归:通过 x,失败 x,跳过 x,未执行 x
- flaky:无 / 已治理(附记录)
## 人工验收
- 验收环境:<预览部署 URL / 构建产物>
- 验收人 / 日期:
- 主路径:通过 / 发现问题(列)
- 异常与权限:通过 / 发现问题
- 界面与副作用:通过 / 发现问题
## 变更审查
- Diff 在 Plan 授权范围内:是 / 否(列越界)
- 无幻觉依赖 / 调试残留:是 / 否
## 未验证 / 无法验证项
- <REQ 或场景>:原因、风险、处理计划
## 已知限制
- <环境、范围、未覆盖的边界>
## 发现并已回流的问题
- <调试中回流 Spec / 补回归用例的记录>Verify 准入准出
准入:
- 全量回归执行完毕,结果诚实分类(第 13 篇);
- 失败项已调试闭环(第 12 篇),无未定位失败;
- 变更已通过代码评审和变更控制(第 09 篇)。
准出(准予发布的条件):
- 需求追踪矩阵每条 REQ 都有充分证据,无未闭合的 P0/P1 项;
- 静态检查、构建、自动化测试全绿,且关键用例证明有效(非陪跑);
- 人工验收在类生产环境完成,主路径和异常路径通过;
- Diff 在授权范围内,无越界、无幻觉、无残留;
- 所有”未验证 / 无法验证”项显式登记,且残留风险被明确接受(由决策人签字);
- 已知限制写清;
- Verify 过程中发现的 Spec 缺口 / 新场景已回流。
Verify 反模式
反模式一:绿即发布。 测试全绿就发,不核对需求覆盖。gap 1–4 全被忽略。对策:以需求追踪矩阵闭合为准出标准。
反模式二:只信自动化。 省略人工验收和生产环境验证。静态站”构建后行为”、交互手感、错误提示,自动化测不真。对策:人工验收 + 预览环境是必选项。
反模式三:全通过报告。 一份没有任何未验证项和已知限制的报告。真实系统必有边界,这种报告说明没认真查。对策:强制三类标注。
反模式四:把未验证项悄悄放过。 “这个回头再说”然后发布。对策:未闭合 P0 项一票否决,要么补验证、要么风险被显式接受并留痕。
失败回退
- 发现需求无证据(gap 1)→ 回到测试设计 / 自动化补用例;
- 发现层级/环境不对(gap 2/3)→ 回到测试执行,在正确层级/生产形态补测;
- 发现测试陪跑(gap 4)→ 回到自动化用例修断言;
- 人工验收发现行为不符 Spec → 回到 Implement(产品 bug)或 Spec(规则空白);
- 发现Spec 没规定的新场景(孤儿文件、审计缺失)→ 回到 Spec 补规则;
- 全部闭合 → 准予发布,线上反馈进入第 15/16 篇的回写闭环。
人审重点
- AI 负责:汇总各类证据、填充追踪矩阵、生成报告初稿、标记未闭合项;
- 人负责:发布决策、人工验收的执行与判断、未验证项风险是否可接受的裁决、已知限制的确认;
- 三条永远不可委托给 AI(第 00 篇责任矩阵)在这里收束:判断测试是否充分、失败归因、发布决策——Verify 正是这三件事集中发生的地方。
结语
Verify 的产出不是一个绿色的对勾,而是一张需求到证据的闭合网。发布的信心不来自”测试没红”,而来自”每一条我们承诺的行为,我都能指出证据,而且我诚实写明了哪些还没验证”。
Verify 会拦住很多问题,但也一定会有漏网之鱼流到线上,或者在测试中反复出现失败。当失败发生时,最关键的能力不是”把它修好”,而是判断”它到底应该在哪一层被修”——是 Spec 错了、Plan 错了、代码错了,还是测试错了。下一篇讲这套归因地图:为什么”修到绿色”是最贵的习惯,以及怎么让每一次失败都回流到它真正的源头。
