| name | test-design |
| description | 基于测试知识库和测试规范,为指定模块或需求 suite 生成 Markdown 用例和 mismatch 记录 |
| when_to_use | 当用户需要为某个模块、L2 需求或独立用例 suite 生成/补充测试用例时 |
| argument-hint | <target> <module> [suite_dir] |
| arguments | ["target","module","suite_dir"] |
| user-invocable | true |
| allowed-tools | Read Glob Grep Write Edit Bash |
| effort | high |
测试用例设计
为 $target 下的 $module 模块,或某个 L2 需求 suite 生成 Markdown 测试用例。
输出目录:$suite_dir。优先使用 test_workspace/suites/{target}/{suite}/ 或用户指定的任意 suite 目录,并在后续 test-scaffold / test-codegen 中由 suite.yaml 绑定 target/module。
前置:读取项目配置
优先读 aitest_config/aitest.yaml,获取:
workspace.paths.* — 知识库、用例、suite、文档等目录路径
targets.registry / modules.registry — 已登记 target/module 的位置
codegen.* — 模块缩写、断言规则、默认请求字段等 codegen 约束
读取 aitest_config/aitest.yaml 获取 workspace 路径、codegen 默认规则和 target/module registry 配置。
读取 test_workspace/targets/{target}/target.yaml(存在时),获取公开接口、route/schema 搜索模式、默认 generated/reports 目录等 target 级信息。
执行流程
第一步:读取规范和上下文
-
读 {paths.test_spec}(TEST_SPEC),建立:
- 编号规则和模块缩写对照表
- 优先级定义(P0/P1/P2)
- 质量红线(Q1-Q10)
- 排除场景列表(生成时跳过)
- 关注场景列表(生成时必须覆盖)
- 已知陷阱列表(生成时逐条自检,避免重犯已知错误模式)
硬约束:在模块缩写对照表中查找 $module 对应的缩写。如果该模块未在表中登记,停止执行,提示用户先在 TEST_SPEC 的"模块缩写对照表"中补登记,避免编号冲突。同一 workspace 存在多个 target 时,仍以 $target/$module 作为定位范围。
-
读 {paths.l0_architecture}(L0),从模块索引表中找到 $module 对应的:
-
读目标 L1 文档,提取:
- 输入/输出定义(请求体结构、字段、类型)— 作为用例"输入"字段的结构基准
- 如果 L1 或 L0 链接了 proto/OpenAPI 文件,读取该文件获取完整的请求/响应字段定义
- 业务规则(逐条编号)
- 错误场景
- 可观测状态
- "已有测试覆盖"章节(已覆盖/未覆盖维度)
-
读关联 L2 文档,提取:
-
搜索已有用例,确定编号起点:
- 新结构优先搜索已指定 suite 目录、
test_workspace/suites/ 中绑定该 module 的 suite,以及 aitest.yaml.workspace.paths.suites_dir
- 找到该模块缩写的最大 TC 序号,新用例从 +1 开始
-
读 aitest_config/refs/assertion-strategy.md,建立断言策略(结构断言 / 关系断言 / 不可程序化断言的选择标准)
第二步:第一轮——业务用例(不看代码)
信息边界:本步骤禁止读取源代码文件(.py/.java/.go/.ts 等)。
- 遍历 L1 "业务规则"章节,每条规则至少生成一条用例
- 遍历 L1 "错误场景"章节,生成异常用例
- 遍历 L2 "新增/变更规则",为新规则生成用例
- 检查排除场景列表 → 跳过匹配的场景类型
- 检查关注场景列表 → 逐项确认已覆盖
- 跳过"已有测试覆盖"中标注为已覆盖的维度(避免与历史用例重复)
- 知识库没说的行为 → 预期结果写
TBD-需确认,不猜测
- 用例的"输入"字段必须基于 L1 文档的输入/输出定义,写出完整请求体结构;L1 未给出完整字段定义的,标注
[!请求体待补全]
- 前置条件必须写出具体构造方式(配置片段、管理 API 请求、测试数据记录、外部依赖状态等),不能只写抽象描述
- 区分可控输入与系统中间产物:请求参数、配置、测试数据、外部依赖状态属于可控输入,可在前置条件中指定具体值;系统运行时计算结果(如派生值、聚合值、排序位次)属于中间产物,不能在前置条件或场景变量中假设其具体值,只能通过调整可控输入间接影响;对中间产物的断言必须使用范围断言或关系断言
- 断言选择遵循
aitest_config/refs/assertion-strategy.md 的三种策略
接口覆盖:查看 L1 "接口"章节,确认模块暴露的接口类型(HTTP / gRPC / 两者)。共享配置可以列出多种接口,但默认 Markdown 用例只生成 JSON 基础请求体;写 协议:gRPC 或 基础请求体(gRPC) 不会阻断默认 JSON 路径,真实 gRPC、SDK 或多端点执行再在后续 suite profile 中通过 case_flows 或 case_bodies 显式接线。
输出格式:默认输出到 $suite_dir/business.md;如果用户指定需求 suite,可输出为 {suite_name}_business.md 等带语义的文件名。按 aitest_config/refs/case-format.md 的"共享配置 + 精简用例"格式。每条用例只写 优先级 / 场景变量 / 断言 三个字段(有特殊状态时加 标记 字段)。场景变量必须写成 key:value 条目列表,[manual]、[!可行性存疑] 等标记写在独立的标记字段,不内联到场景变量或断言中。test-design 只产出 Markdown 用例,不写 suite.yaml 和 suite profile;这些由 test-scaffold / test-codegen 接线。
第三步:第二轮——边界用例(读代码)
- 通过 Glob/Grep 搜索项目中与
$target/$module 相关的源代码文件
- 读源代码,识别以下边界场景并生成用例:
- 降级逻辑(try/except、默认值返回)
- 类型转换(隐式转换、强制转换)
- 容错处理(空值、None、空列表)
- 精度处理(round、截断)
- 未在知识库中记录的条件分支
- 校验第一轮用例的可行性:
- HTTP 路由校验:如果
target.yaml 声明了 service.route_patterns,按该模式搜索路由;否则以文档、OpenAPI/proto 或用户指定入口为准,必要时标 [!可行性存疑]
- 请求体 Schema 校验:如果
target.yaml 声明了 service.schema_patterns,按该模式搜索 Schema;否则读取 OpenAPI/proto/JSON Schema 等公开接口定义,逐字段核对请求体(必填字段必须存在,嵌套结构也要检查)
- 前置条件是否可通过代码构造
- 输入格式是否与代码接口匹配
- 补全标注了
[!请求体待补全] 的用例
- 有问题的用例追加标注
[!可行性存疑: 原因]
- 发现规格与实现不一致时 → 不修改第一轮用例,按
aitest_config/refs/mismatch-format.md 新建 mismatch 记录。如果 $suite_dir/mismatch.md 已存在,新条目追加在文件末尾,不删除/覆盖已有条目,编号从已有最大序号 +1 继续
- 第一轮中标记
TBD-需确认 的预期结果,如果代码能给出答案,在 business.md 中更新并标注来源
默认输出到 $suite_dir/boundary.md,使用与 business.md 相同的共享配置格式;suite 模式可使用 {suite_name}_boundary.md 等带语义的文件名。
Mismatch 输出到 $suite_dir/mismatch.md(无则不创建)。
第四步:覆盖变更与知识库刷新
- 汇总本次新增用例覆盖的维度
- 对比 L1/L2 文档"已有测试覆盖"章节中的"未覆盖"列表
- 在 business.md 和 boundary.md 末尾各附覆盖变更清单:
## 覆盖变更
| 知识库文档 | 新增覆盖 | 仍未覆盖 |
|-----------|---------|---------|
| L1/xxx | 维度 A、维度 B | 维度 C |
- 更新 L1/L2 文档的"已有测试覆盖"章节:
- 将新覆盖的维度从"未覆盖"移到"已覆盖"
- 添加用例文件引用
第五步:完成输出与反馈收集
执行完毕后,向用户输出:
## 用例生成摘要
目标:$target
目标模块:$module
输出目录:$suite_dir
### 生成文件
| 文件 | 用例数 | 类型 |
|------|-------|------|
| business.md | N 条 | 业务 + 异常 |
| boundary.md | N 条 | 边界 |
| mismatch.md | N 条 | 规格偏差 |
### 覆盖变更
| 知识库文档 | 新增覆盖维度 | 仍未覆盖维度 |
### TBD 项
(列出所有预期结果为 TBD-需确认 的用例,需用户或产品确认)
### 可行性存疑
(列出所有标注了 [!可行性存疑] 的用例)
然后询问用户:
- 请评审用例,有无需要调整的
- 有没有不值得测的场景类型?(补充到 TEST_SPEC 排除场景)
- 有没有遗漏的必测场景?(补充到 TEST_SPEC 关注场景)
如果用户给出排除/关注反馈 → 更新 {paths.test_spec} 对应章节。
质量自检
生成每条用例后,对照以下两组规则逐条检查,不通过的用例必须修正后再输出:
- TEST_SPEC 质量红线(Q1-Q10)— 用例可执行性的硬性要求
- TEST_SPEC 已知陷阱(全部条目,不限于已编号的最早三条)— 历史错误模式自检;陷阱列表会随 test-fix 持续扩展,每次生成时读取当前完整列表逐条核对
增量模式
当 $suite_dir 下已有 business.md 或 boundary.md 时,先询问用户选择处理方式:
- 追加新用例:识别已覆盖场景,追加新用例到末尾
- 重新生成:把已有文件备份为
*.md.bak,从零生成全部用例
用户选择追加时,继续询问用例来源:
- 从知识库补充:自动从知识库识别未覆盖场景,生成新用例(原有逻辑)
- 手动描述补充:用户用自然语言描述想要添加的测试场景,AI 翻译为符合格式规范的用例写入 Markdown
格式兼容检测:检查已有文件是否包含 ## 共享配置 块。
- 是新格式 → 按用户选择执行
- 是旧版完整格式 → 追加模式会破坏共享配置语义;停下来明确告知用户,建议改为"重新生成"或先手动迁移已有用例
确认选择后再执行。
追加模式——从知识库补充
- 读取已有用例,理解已覆盖的场景
- 只生成未覆盖的新用例
- 新用例追加到已有文件末尾(覆盖变更清单之前)
- 编号从已有最大序号 +1 继续
追加模式——手动描述补充
- 读取已有用例文件,理解共享配置和已有用例的格式
- 请用户描述要添加的用例(可以一次描述多条),接受自然语言,例如:
- "加一条测试:当资源余量为 0 时请求接口,应该返回空列表"
- "补一个边界:user_id 为空字符串的情况"
- "测试并发场景:同一用户同时发两个创建请求,不应重复创建记录"
- 根据用户描述,结合已有共享配置和项目上下文,生成符合
case-format.md 格式的用例:
- 编号从已有最大序号 +1 继续
- 复用已有共享配置(接口、基础请求体等)
- 场景变量写成
key:value 条目列表
- 断言选择遵循
assertion-strategy.md 的三种策略
- 用户描述中不明确的部分主动询问,不猜测
- 生成后展示给用户确认,确认后写入对应的 Markdown 文件
- 对生成的用例执行质量自检(TEST_SPEC 红线 + 陷阱)
重新生成的执行规则
- 把已有 business.md / boundary.md / mismatch.md 改名加
.bak 后缀
- 按完整流程从零生成,编号从 001 开始