【AI Native开发-14】42 个测试全绿,为什么仍不能证明需求完成?
30 秒看懂这篇
42 个测试全绿,仍然可能有 3 条需求从未被验证。绿色回答的是“这些测试通过了”,Verify 回答的则是:“我们承诺的行为,有足够证据支持吗?”
flowchart TB
R["REQ:承诺什么"] --> T["TEST:如何检验"]
T --> X["执行:在哪一层、什么环境"]
X --> V["证据:结果、日志与人工记录"]
V --> D{"证据充分吗?"}
D -->|"是"| OK["Verified:有充分证据"]
D -->|"否"| GAP["标出缺口与残留风险"]
GAP --> T核心论点:
- 测试通过是手段,需求有证据才是目的。 漏测、错误层级和陪跑断言,都可能藏在全绿报告后面。
- 证据要按需求归集。 REQ → TEST → 执行 → 证据必须能逐行追踪,不能只给一张测试总数截图。
- 边界必须诚实。 “未验证”和“无法自动化、已人工验证”是不同状态,不能混成一个模糊的人工项。
本篇给出证据充分性判据、按风险安排的人工验收、已知限制,以及可直接使用的 Verify 报告。
一个典型场景
接着第 13 篇:失败已修复、跳过与阻塞项也已补齐,第二轮全量回归得到 42 个通过、0 个失败;类型检查、单元、接口、构建和 E2E 均已执行。AI 报告:“所有测试通过,功能完成。”
发布前你按 Verify 的思路核对,发现:
- REQ-006”删除失败时列表保持原状态并提示错误”——翻遍测试,没有一条用例覆盖失败提示的界面表现,接口层只测了返回码;
- REQ-005 里”删除后刷新页面文章仍不可见”——自动化测了接口返回 404,但没测静态站重新构建后列表真的少了这篇(dev 模式下文件删了但列表可能还是旧的);
- “二次确认弹窗”的交互——只有 E2E 测了”取消不发请求”,“确认后真的删除”这条主路径在界面层没人点过;
- 删除后共享图片是否保留、详情 URL 如何表现没有定义——这是 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-001-1 api/delete E2E 通过 204 + 文件消失 + E2E确认路径 ✓
REQ-002 仅管理员可删 TEST-002-1~3 api/delete 通过 401/403且文件仍在 ✓
REQ-003 已公开文章不可删 TEST-003-1/2 api/delete 通过 409且文件仍在 ✓
REQ-004 取消确认不删除 TEST-004-1 e2e/cancel 通过 监听到无DELETE请求 ✓
REQ-005 删除后重建仍不存在 TEST-005-1 build/preview 部分 构建产物尚未确认 ✗
REQ-006 失败时保持列表状态 TEST-006-1/2 (仅接口返回码) 部分 界面失败提示【未验证】✗
REQ-007 目标不存在/重复删除 TEST-007-1/2 api/delete 通过 返回 404 且无额外副作用 ✓逐行核对三个问题:
- 每行都有证据吗? REQ-006 这一行,自动化只到接口返回码,界面失败提示没有证据 → 标记为未闭合;
- 证据在正确的层级和环境吗? REQ-005“删除后重建仍不存在”需要在构建产物上验证 → dev 层的证据不够;
- 证据有效吗? 对关键用例做有针对性的变异检查,例如换成“所有删除都成功”的错误实现,确认权限断言会变红。
矩阵里任何一行出现“无证据 / 部分 / 未验证”,就不能把这条需求标为已验证。 这张表把“我觉得测过了”变成“REQ-006 缺一条界面失败提示的证据”。
证据充分性判据
对每条已闭合的 REQ,还要判断证据是否“充分”,而不只是“有”。判据:
充分的证据:
✓ 验证了行为和副作用(不只状态码,还验证数据状态)
✓ 在能真实复现该行为的层级(静态站行为在构建产物上验)
✓ 权限/异常用例验证了"没造成破坏"
✓ 关键用例对选定错误实现敏感,不是陪跑
✓ 结果可复现;重试历史完整,flaky 单独报告
不充分的证据(即便最终变绿):
✗ 只断言"没报错""函数被调用"
✗ 关键依赖被 mock 掉(如权限中间件被 mock)
✗ 只在 dev 验证了生产形态才有的行为
✗ 隐藏首次失败,只展示重试后的绿色
✗ 断言与 Spec 措辞对不上(测的不是需求要的)人工验收清单
按风险选取以下项目,在预览/类生产环境执行;每条都要记录验收人、环境和结果:
【主路径】
□ 管理员删除未公开文章:确认弹窗 → 确认 → 文章消失
□ 刷新 / 重新构建后,文章确实不在列表
□ 删除后的详情 URL 行为符合 Spec
【异常与权限】
□ 普通用户入口与服务端拦截表现一致
□ 删除失败时列表不乱、提示清晰、数据没丢
□ 已公开文章被明确拒绝并说明原因
【界面与副作用】
□ 二次确认文案与按钮行为清晰
□ 列表、标签、搜索、图片资源符合 Spec
□ (如 Spec 要求)删除操作有审计记录
【环境差异】
□ 在生产构建产物或预览部署上验证
□ 已核对本地与部署环境的关键差异人工验收发现“Spec 没规定但不合理”的现象(比如删除后图片成了孤儿文件),要回流 Spec,而不是当场拍一个处理方式。
诚实标注:已验证 / 未验证 / 人工验证
一份可信的 Verify 报告,要区分状态和验证方式:
【已验证(Verified)】
有充分证据支持满足 Spec。列出 REQ、证据和适用边界。
【未验证(Not verified)】
应该测但还没测 / 证据不足。说明缺口、风险和补验计划。
高风险未闭合项不得准出;其他残留风险须由决策人显式接受。
【人工验证(Manual)】
一种执行方式,不是验证结果。必须另外标记 Verified / Not verified,
并记录验证人、环境与结论。
【无法自动化(Cannot automate)】
说明当前不能自动化的原因(如主观体验),
通常转人工验证;不代表“不需要验证”。
【已知限制(Known limitations)】
本次明确不覆盖的范围及环境差异。诚实标注不是报告污点,而是报告可信的来源。决策者需要看到“什么有证据、什么仍未知、谁接受了哪项风险”。
Verify 报告模板
# Verify Report: <功能名>
## 结论
- [ ] P0 / P1 需求均有充分证据,且其他准出条件全部满足,准予发布
- [ ] 存在 P0 / P1 未闭合项或其他准出条件未满足,不准予发布(见下)
## 需求追踪矩阵(闭合状态)
| REQ | 摘要 | 文本用例 | 自动化 | 结果 | 证据 | 状态 |
|-----|------|---------|--------|------|------|------|
| ... | ... | ... | ... | ... | ... | ✓/✗/部分 |
## 静态证据
- 类型检查:通过 / 失败
- lint:通过 / 失败
- 生产构建:通过 / 失败(静态站必查)
## 自动化执行摘要
- 冒烟:x/x 通过
- 受影响:x/x 通过,失败/跳过明细
- 全量回归:通过 x,失败 x,跳过 x,未执行 x
- flaky:无 / 已治理(附记录)
## 人工验收
- 验收环境:<预览部署 URL / 构建产物>
- 验收人 / 日期:
- 主路径:通过 / 发现问题(列)
- 异常与权限:通过 / 发现问题
- 界面与副作用:通过 / 发现问题
## 变更审查
- Diff 在 Plan 授权范围内:是 / 否(列越界)
- 无幻觉依赖 / 调试残留:是 / 否
## 未验证 / 无法验证项
- <REQ 或场景>:原因、风险、处理计划
## 已知限制
- <环境、范围、未覆盖的边界>
## 发现并已回流的问题
- <调试中回流 Spec / 补回归用例的记录>Verify 准入准出
准入:
- 全量回归执行完毕,结果诚实分类(第 13 篇);
- 失败项已调试闭环(第 12 篇),无未定位失败;
- 变更已通过代码评审和变更控制(第 09 篇)。
准出(准予发布的条件):
- 需求追踪矩阵覆盖每条 REQ;P0/P1 均有充分证据,无未闭合项;
- 约定的静态检查、构建和自动化范围通过,关键用例对选定错误实现敏感;
- 按风险计划的人工验收已在类生产环境完成,结果与环境有记录;
- Diff 在授权范围内,无越界、无幻觉、无残留;
- 所有未验证项和无法自动化项分别登记;只有 P2 或其他非关键残留风险可按既定规则由有权决策的人显式接受,并记录理由与补偿措施;
- 已知限制写清,Spec 缺口和新场景已回流。
Verify 反模式
反模式一:绿即发布。 测试全绿就发,不核对需求覆盖。对策:以需求追踪矩阵和证据充分性为准出标准。
反模式二:只信自动化,或所有事项都人肉重测。 前者漏掉主观体验,后者浪费评审时间。对策:按风险选择人工验收,能可靠自动化的行为优先自动化。
反模式三:全通过报告。 没有任何边界和已知限制,往往说明没有认真查。对策:显式标注未验证、人工验证和已知限制。
反模式四:把未验证项悄悄放过。 “这个回头再说”然后发布。对策:未闭合 P0 / P1 项不得发布,必须补齐证据;P2 或其他非关键残留风险只能按既定规则显式接受并留痕。
回退与责任
覆盖缺口回测试设计,层级或环境缺口回测试执行,陪跑断言回自动化;行为不符 Spec 回 Implement,规则空白回 Spec。AI 可汇总证据和标记缺口,人负责证据充分性、失败归因、残留风险与发布决策。
结语
Verify 的产出不是一个绿色的对勾,而是一张需求到证据的闭合网。发布的信心不来自”测试没红”,而来自”每一条我们承诺的行为,我都能指出证据,而且我诚实写明了哪些还没验证”。
Verify 会拦住很多问题,但也一定会有漏网之鱼流到线上,或者在测试中反复出现失败。当失败发生时,最关键的能力不是”把它修好”,而是判断”它到底应该在哪一层被修”——是 Spec 错了、Plan 错了、代码错了,还是测试错了。下一篇讲这套归因地图:为什么”修到绿色”是最贵的习惯,以及怎么让每一次失败都回流到它真正的源头。
