Vibe Coding 测试矩阵:把 Happy Path、边界与状态转换放进一张表
AI 按代码分支补测试,容易得到很多案例却漏掉关键状态组合。本文用场景轴、边界轴和状态转换轴构建可裁剪矩阵,让每个用例都有风险来源与明确预言。
本文要点
- 主题聚焦:Vibe Coding、AI Agent、TypeScript、DevOps
- 适合人群:独立开发者、全栈工程师、AI 应用开发者
- 核心价值:快速理解背景、实践路径、常见误区和工程建议
“为注册流程补全测试”常得到一串看似丰富的用例:正确邮箱成功、错误邮箱失败、空密码失败、重复邮箱失败。它们覆盖了输入分支,却可能都从同一个初始状态出发;真正危险的“验证码已过期后重发”“请求正在处理中再次提交”“账户已存在但未验证”仍然没有出现。案例数量不是覆盖设计,分支覆盖率也不能替代业务状态覆盖。
测试矩阵把设计工作放在生成代码之前。它先列出场景、边界和状态转换,再选择有风险意义的交叉点。AI 的角色是根据批准的行生成 fixture 与测试实现,不是从当前 if 语句反推全部需求。分层思路可结合Agent 测试策略,本文聚焦单个用户流程如何形成可审查的用例集合。
三个轴分别回答三个问题
第一轴是场景,也就是用户要完成什么。至少包含一个 happy path、每种业务拒绝、外部依赖失败和取消/重试。第二轴是数据边界:空值、最小值、刚好等于阈值、刚好越界、Unicode、重复值和超长值。第三轴是状态:初始状态、处理中、成功、失败、超时、取消以及允许恢复的状态。
以邀请码注册为例,可以先写一张设计表:
| ID | 起始状态 | 输入类别 | 外部响应 | 期望终态 | 主要观察 |
|---|---|---|---|---|---|
| R1 | idle | 合法邮箱和邀请码 | 成功 | verified | 创建一次账户 |
| R2 | idle | 邀请码刚好过期 | 未调用 | rejected | 明确过期错误 |
| R3 | submitting | 再次提交同一请求 | 未调用 | submitting | 不产生第二次写入 |
| R4 | idle | 合法输入 | 邮件服务超时 | pending | 可安全重试且不重复建账 |
| R5 | pending | 重发请求 | 成功 | verified | 沿用同一账户身份 |
这张表故意不把所有列做笛卡尔积。空邮箱和邮件服务超时没有组合价值,因为输入校验应在调用外部服务前结束。每一行都要注明风险来源:验收条件、历史缺陷、状态图、协议约束或 reviewer 判断。没有来源的随机排列先不生成。
先画转换,再写断言
状态流程可写成 state + event -> nextState + effects。W3C SCXML 给出了状态机的标准表达方式;项目不必采用 SCXML,也可以借它检查是否遗漏事件、守卫和终态。对每条允许转换至少安排一个正例,对每条高风险禁止转换安排一个负例。
idle + submit(valid) -> submitting + requestCreate
submitting + submit(valid) -> submitting + noEffect
submitting + timeout -> pending + showRetry
pending + retry -> submitting + requestStatus
verified + retry -> verified + noEffect
断言应同时覆盖结果与副作用。只断言页面显示“成功”,无法发现后台写了两次;只断言 repository 被调用一次,又无法证明用户看到了可恢复状态。测试预言如何选择可进一步参考Vibe Coding 测试预言审查,矩阵只负责确保问题被问到。
用等价类控制组合爆炸
边界值不是把每个字段随意取三个值。先按业务规则分等价类,例如邀请码可分为有效、已使用、过期、格式非法;时间边界选择到期前一刻、恰好到期和到期后一刻。若有五个字段,每个三种值,完整组合会迅速失控。保留每条规则的单因素边界,再为会相互影响的字段增加成对组合。
高风险组合由不变量驱动:金额与币种共同决定精度,角色与资源归属共同决定授权,状态与幂等键共同决定重复副作用。低风险展示字段不必与所有错误状态交叉。需要探索更大空间时,使用AI 生成代码的属性测试生成数据,并保留失败种子;不要把数千个随机输入伪装成数千个独立设计决策。
让矩阵和测试代码可互相追踪
每个测试名带矩阵 ID,参数化运行减少样板代码。Jest 的 test.each 和 Node Test Runner 的子测试都能承载表格案例,但框架不会替你判断表格是否完整。测试报告应能从失败的 R4 回到这一行的起始状态、触发事件和预期副作用。
AI 生成实现前,把矩阵作为只读输入,并明确:不得删除行,不得合并语义不同的错误,不得为了复用 fixture 改写期望。生成后检查测试是否真的使用了行内数据;常见错误是循环变量写了很多,断言却始终读取同一个默认 fixture。完整 diff 仍要经过AI Code Review 实践,尤其关注跳过、重试和过宽匹配器。
矩阵还需绑定版本。需求、状态图或 API 契约改变时,先更新表并审阅差异,再更新测试。只改测试代码会让设计依据消失。每行至少保留 caseId、风险、输入类、起始状态、事件、预期终态、副作用和证据来源;是否自动化则是另一个字段,不能因暂时无法自动化就从矩阵删除。
用门禁检查“漏了什么”
完成标准不是所有行变绿,而是:每项验收至少映射一行;每个业务终态可到达;关键禁止转换有负例;外部失败有恢复或明确终止;边界选择能回到规则;测试结果绑定当前 HEAD。若选择性执行,还要说明为什么这些用例覆盖了 diff,可参考编程 Agent 的测试影响分析。
失败时不要让 AI 立即改断言。先判断矩阵是否写错、需求是否歧义、实现是否违反转换,或 fixture 是否没有建立声称的起始状态。矩阵的价值正是把这些问题分开。它让 Vibe Coding 的“多写一些测试”变成一组有限、可解释的风险采样:happy path 证明任务可完成,边界证明规则在阈值处成立,状态转换证明系统经过失败和重试后仍不会走到非法位置。
延伸阅读
Related