【AI Native开发-10】测试设计:从 Spec 生成文本用例
摘要
从这一篇开始进入测试与验证线。测试的源头不是测试代码,而是文本测试用例——把 Spec 里的每条需求,系统地翻译成”在什么条件下、做什么操作、应该看到什么”的可执行描述。
核心论点:
- “测什么”不能凭经验,必须从 Spec 推导。 凭经验想测试用例,一定会漏;从 REQ 编号逐条推导,才能保证每条需求都被验证。这个 REQ → TEST 的映射,就是需求追踪矩阵的起点。
- 文本用例是人和 AI 的共同语言。 人审业务风险和遗漏(AI 不懂业务,会漏掉”删除连带图片”这类场景),AI 负责把用例铺全、格式统一。文本用例还是下一步生成自动化代码的输入。
- 用例的价值在”断言什么”,不在”步骤多全”。 一条好用例的核心是它的预期结果——尤其是那些”什么都不该发生”的副作用断言。
本篇给出用例推导方法、六个覆盖维度、Given/When/Then 写法、需求追踪矩阵,以及文本用例的准入准出。
一个典型场景
删除文章功能要测了。你让 AI”给删除功能写点测试用例”,它很快给出一份:
1. 管理员删除草稿文章,成功
2. 删除后文章不在列表里
3. 删除时有确认弹窗看起来没错,但这份用例漏掉了最危险的东西:
- 普通用户 / 未登录用户能不能删?(权限)
- 已发布文章能不能删?(状态约束)
- 重复点删除、同时发两个删除请求会怎样?(幂等 / 并发)
- 删除失败时列表状态对不对?(异常)
- 删除请求被拒后,文件到底还在不在?(副作用)
- 取消确认时到底有没有发请求?(非目标行为)
AI 给的三条全是” happy path “。这不是它偷懒,是你没给它推导用例的锚点。“写点测试”这种指令,它只能按最常见的正常流程铺。要让它测全,必须让它对着 Spec 的每条 REQ、按固定维度去穷举。
核心问题:为什么先写文本用例,不直接写测试代码
有人会问:AI 写测试代码很快,为什么还要多此一举先写一遍中文文本用例?
三个原因:
- 文本用例的评审成本极低。 看一句”普通用户删除应返回 403 且文件仍在”,任何人都能判断对不对;看一段测试代码,要理解 mock、fixture、断言,业务同学根本参与不了。文本用例让产品、测试、开发在同一张桌子上评审”测什么”。
- 文本用例是防漏的网。 在中文层面把”权限、异常、并发、边界”穷举一遍,比在代码层面补便宜得多。漏一条用例在评审时发现是改一行字,漏在自动化里是一个没被测的风险。
- 文本用例是自动化的稳定输入。 下一篇用 AI 把文本用例翻译成测试代码时,每条 TEST 都对应明确的 Given/When/Then,翻译就不会跑偏。直接让 AI 从 Spec 蹦到测试代码,中间缺了”测哪些场景”的显式决策。
一句话:**文本用例回答”该测哪些情况”,自动化用例回答”怎么用代码测这些情况”。把两个问题混在一起,两个都做不好。
正确流程:从 REQ 逐条推导用例
本文的删除接口、HTTP 状态码和测试路径均为假想全栈项目示例;本博客当前没有这些运行时 API 或测试脚本,真实项目应先以代码和
package.json核实。
第一步:列出需求追踪矩阵的骨架
把 Spec 里所有 REQ 编号列出来,作为用例的源头:
REQ-001 管理员可删除未公开文章(hide: true),删除后文章不可见
REQ-002 仅管理员可删除;非管理员调用返回 403,且无副作用
REQ-003 已公开文章(hide: false 或缺省)不可删除,返回 409
REQ-004 删除前需二次确认;取消则不执行删除
REQ-005 删除后重新构建仍不存在
REQ-006 删除失败时,列表保持原状态,给出错误提示规则:每条 REQ 至少有一个用例覆盖;没有对应用例的 REQ,就是没被测的需求。
第二步:对每条 REQ,按六个维度展开场景
不要只写正常情况。对每条需求,依次过这六个维度,看哪些适用:
1. 正常(happy path):满足所有条件,操作成功
2. 权限:不同角色(管理员/普通用户/未登录)、越权访问
3. 异常:操作失败(网络错、依赖失败、校验不通过)时的行为
4. 边界:状态边界(hide: true 未公开 / hide: false 已公开)、参数边界
(不存在的 id、非法 id)、空值
5. 并发 / 幂等:重复提交、同时提交、重试
6. 可恢复 / 副作用:操作后系统状态对不对?
失败后数据有没有被破坏?不该发生的副作用有没有发生?以 REQ-002(仅管理员可删除)为例,展开后:
TEST-002-1 对照:管理员删除未公开文章(hide: true)→ 200,文章消失
TEST-002-2 权限:普通用户调用删除 → 403,文件仍在(副作用!)
TEST-002-3 权限:未登录调用删除 → 401,文件仍在
TEST-002-4 权限:普通用户伪造请求直接打接口(绕过前端按钮)
→ 仍被服务端拦截 403(属于 REQ-002 的无副作用验证)
TEST-007-2 异常:删除一个不存在的 id → 404,不报错崩溃注意 TEST-002-2 和 002-4 都带了副作用断言——不只是”返回 403”,还要确认”文件还在”。这是文本用例最容易漏、也最有价值的部分。
第三步:用 Given/When/Then 写清楚
每条用例用统一结构,避免”步骤写一堆、预期一句话”:
TEST-002-2 普通用户不能删除未公开文章(权限 + 副作用)
Given 普通用户已登录,存在一篇未公开文章(hide: true,id=A1,文件存在)
When 该用户调用删除接口 DELETE /api/articles/A1
Then 接口返回 403
And 文章文件 A1 仍然存在(重新查询返回 200)
And 列表中该文章仍可见
And 没有任何删除相关的副作用发生(图片、索引不受影响)
TEST-003-1 已公开文章不可删除(状态边界)
Given 管理员已登录,存在一篇已公开文章(hide: false,id=A2)
When 调用删除接口 DELETE /api/articles/A2
Then 接口返回 409(或约定的业务错误码)
And 文章文件 A2 仍然存在
And 错误提示说明"已公开文章不可删除"
TEST-004-1 取消确认不执行删除(非目标行为)
Given 管理员已登录,在列表页点击未公开文章的删除按钮
When 弹出确认框后,点击"取消"
Then 不发起任何删除请求(断言:无 DELETE 请求发出)
And 文章文件仍然存在
TEST-007-1 重复提交删除的结果明确(并发/幂等)
Given 管理员已登录,存在一篇未公开文章(hide: true,id=A3)
When 短时间内连续发起两次删除请求
Then 第一次返回成功;第二次返回 404(文章不存在)而非 500
And 系统不出现重复操作导致的错误状态TEST-004-1 值得专门说:它断言的是**“什么都没发生”**。这类用例最容易被漏——大家都想着测”点了确认能删”,没人想测”点了取消是不是真的没动”。但 REQ-004 的本质就是”取消 = 无副作用”,不测它,这条需求等于没验证。下一篇会看到,这个用例在自动化里用 Playwright 监听 DELETE 请求来实现。
第四步:人审业务风险和遗漏
AI 可以把上面三步铺得很全(给它 REQ 清单和六个维度,它能批量生成),但有一类东西它补不了——业务里”理所当然”的隐含场景。这是人的专属审查项:
人工审查必问:
- 删除文章,它引用的图片 / 附件 / 封面怎么办?(级联副作用)
- 删除后,文章的 URL 直接访问会怎样?列表、标签、搜索结果呢?
- 删除操作要不要记日志 / 审计?谁删的能不能追溯?
- 删除有没有误触风险?批量操作会不会一次删错?
- 已被收藏 / 引用 / 评论的文章删除,关联数据怎么办?这些问题 AI 问不出来,因为它们依赖对这个具体业务的理解。文本用例阶段让人(产品 / 老员工)参与,成本最低、收益最大——这正是把测试设计放在自动化之前的原因。发现”删除连带图片”该怎么处理,是 Spec 层面的规则问题,在这儿暴露了就回流到 Spec,而不是等上线后攒一堆孤儿文件。
需求追踪矩阵(测试侧)
文本用例完成后,形成 REQ → TEST 的追踪表:
REQ 编号 需求摘要 覆盖用例
REQ-001 管理员删未公开文章成功 TEST-002-1(对照)
REQ-002 仅管理员可删除 TEST-002-1~5
REQ-003 已公开文章不可删 TEST-003-1, TEST-003-2
REQ-004 取消确认不删除 TEST-004-1
REQ-005 删除后重建仍不存在 AC-1 / 人工构建验收
REQ-006 失败时保持列表状态 TEST-006-1, TEST-006-2
REQ-007 目标不存在/重复删除 TEST-007-1, TEST-007-2
检查:
- 每个 REQ 至少有一个 TEST? (无 = 漏测需求)
- 每个 TEST 都能追溯到某个 REQ? (无 = 测了不需要的东西)
- 权限/异常/副作用类用例占比合理吗? (全是 happy path = 测试设计失败)这张矩阵会在后面一路延伸:TEST → 自动化代码 → 执行结果 → Verify 证据。它是整条测试线的脊梁。
每条用例要带的元信息
除了 Given/When/Then,用例还要标注:
TEST-xxx-<序号>
- 优先级:P0(核心,阻塞发布)/ P1(重要)/ P2(一般)
- 风险维度:正常/权限/异常/边界/并发/副作用
- 前置数据:需要什么状态的文章、什么角色登录
- 环境要求:是否依赖特定环境(如生产构建行为)
- 自动化建议:单元 / 接口 / E2E 哪一层(下一篇用)优先级用来决定执行顺序:P0 全绿才能准出,P2 失败可能不阻塞但要记录。
文本用例准入准出
准入:
- Spec 已过 Gate 1,REQ 编号齐全;
- 有明确的角色、状态、权限定义;
- 业务隐含场景经过人工确认(级联、审计、关联数据)。
准出:
- 每条 REQ 至少有一条可执行用例,矩阵无空行;
- 每条用例有明确的前置、操作、预期结果(含副作用断言);
- 六个维度都过了一遍,权限 / 异常 / 边界 / 副作用类用例占比合理;
- 没有”应该正常""提示错误”这种模糊预期——预期必须具体到状态码、数据状态、界面表现;
- 隐含业务场景经人审过,发现的规则缺口已回流 Spec;
- 每条用例标注了优先级和建议测试层级。
测试设计反模式
反模式一:只写 happy path。 AI 默认倾向 + 人懒得想异常,导致用例全是”正常操作成功”。权限、异常、副作用才是 bug 藏身处。对策:六维度强制逐项过。
反模式二:预期结果写”功能正常”。 “删除后应该正常""提示错误信息”——这种预期无法判定通过还是失败。好的预期具体到:返回什么码、数据变成什么、界面表现如何。
反模式三:只断言动作,不断言副作用。 “返回 403”不等于”没造成破坏”。必须补”文件还在、数据没变、无副作用”。权限和异常用例尤其如此。
反模式四:跳过文本用例直接写代码。 看似省一步,实际把”测什么”的决策混进了”怎么测”的代码里,业务同学无法参与评审,遗漏场景直到上线才暴露。
失败回退
- 写用例时发现 Spec 规则不明确(如”删除后图片怎么办”没规定)→ 回到 Spec 补规则;
- 发现需求之间矛盾 → 回到 Spec;
- 用例铺出来发现某条 REQ 无法验证(没有可观察的结果)→ 说明 Spec 的验收标准不可测,回到 Spec 重写验收标准;
- 用例本身逻辑错(预期和 Spec 不一致)→ 在测试设计阶段修正,留痕。
人审重点
- AI 负责:按 REQ + 六维度铺用例、统一格式、建追踪矩阵;
- 人负责:业务隐含场景(级联、审计、关联数据)、判断优先级是否合理、预期结果是否符合业务预期、确认每个 REQ 真的被测到了;
- 发现的任何”Spec 没规定”的场景,都是 Gate 1 漏网的需求,必须回流。
结语
测试用例的数量不重要,重要的是每条需求都有一个能证明它成立或不成立的场景。文本用例就是把”我觉得测过了”变成”我能指出 REQ-002 被 TEST-002-4 验证着”的那张网。
文本用例回答了”测哪些场景”。下一篇解决”怎么用代码把这些场景测起来”:怎么让 AI 把 Given/When/Then 可靠地翻译成单元、接口、E2E 自动化代码——为什么先选测试层级再写、为什么要复用项目现有的 fixture 而不是让 AI 新造一套、怎么断言业务不变量而不是绑定实现细节,以及怎么保证每条自动化用例都能回溯到它对应的那条文本用例。
