cgraphx 1.2.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.claude-template/hooks/precommit-check/precommit-check.cjs +90 -0
- package/dist/.claude-template/skills/cgraphx-guide/how-to-use.html +100 -78
- package/dist/.claude-template/skills/precommit-review/SKILL.md +50 -0
- package/dist/.claude-template/skills/run-api-test/SKILL.md +187 -0
- package/dist/.claude-template/skills/run-api-test/assets/template-test-report.md +103 -0
- package/dist/.claude-template/skills/run-api-test/assets/template-test-verify.jsonl +5 -0
- package/dist/.claude-template/skills/run-api-test/references/bru-run.md +60 -0
- package/dist/.claude-template/skills/run-api-test/references/db-verification.md +81 -0
- package/dist/.claude-template/skills/run-api-test/references/report-format.md +104 -0
- package/dist/.claude-template/skills/run-api-test/references/service-readiness.md +61 -0
- package/dist/.claude-template/skills/run-api-test/references/test-scope.md +64 -0
- package/dist/.claude-template/skills/write-api/SKILL.md +150 -0
- package/dist/.claude-template/skills/write-api/assets/template-api-spec.md +112 -0
- package/dist/.claude-template/skills/write-api/assets/template-request.bru +72 -0
- package/dist/.claude-template/skills/write-api/references/ai-prompts.md +133 -0
- package/dist/.claude-template/skills/write-api/references/api-spec-format.md +108 -0
- package/dist/.claude-template/skills/write-api/references/bru-format.md +139 -0
- package/dist/.claude-template/skills/write-api/references/collection-layout.md +90 -0
- package/dist/.claude-template/skills/write-api/references/environment-setup.md +105 -0
- package/dist/.claude-template/skills/write-api/references/interface-scope.md +74 -0
- package/dist/api-test/ai-fields.d.ts +37 -0
- package/dist/api-test/ai-fields.d.ts.map +1 -0
- package/dist/api-test/ai-fields.js +114 -0
- package/dist/api-test/ai-fields.js.map +1 -0
- package/dist/api-test/assemble.d.ts +76 -0
- package/dist/api-test/assemble.d.ts.map +1 -0
- package/dist/api-test/assemble.js +185 -0
- package/dist/api-test/assemble.js.map +1 -0
- package/dist/api-test/bru-cli-invoker.d.ts +72 -0
- package/dist/api-test/bru-cli-invoker.d.ts.map +1 -0
- package/dist/api-test/bru-cli-invoker.js +169 -0
- package/dist/api-test/bru-cli-invoker.js.map +1 -0
- package/dist/api-test/bru-report-parser.d.ts +24 -0
- package/dist/api-test/bru-report-parser.d.ts.map +1 -0
- package/dist/api-test/bru-report-parser.js +110 -0
- package/dist/api-test/bru-report-parser.js.map +1 -0
- package/dist/api-test/bru-runner.d.ts +101 -0
- package/dist/api-test/bru-runner.d.ts.map +1 -0
- package/dist/api-test/bru-runner.js +316 -0
- package/dist/api-test/bru-runner.js.map +1 -0
- package/dist/api-test/bru-writer.d.ts +52 -0
- package/dist/api-test/bru-writer.d.ts.map +1 -0
- package/dist/api-test/bru-writer.js +159 -0
- package/dist/api-test/bru-writer.js.map +1 -0
- package/dist/api-test/call-chain-extractor.d.ts +80 -0
- package/dist/api-test/call-chain-extractor.d.ts.map +1 -0
- package/dist/api-test/call-chain-extractor.js +179 -0
- package/dist/api-test/call-chain-extractor.js.map +1 -0
- package/dist/api-test/cli.d.ts +133 -0
- package/dist/api-test/cli.d.ts.map +1 -0
- package/dist/api-test/cli.js +1009 -0
- package/dist/api-test/cli.js.map +1 -0
- package/dist/api-test/config.d.ts +75 -0
- package/dist/api-test/config.d.ts.map +1 -0
- package/dist/api-test/config.js +406 -0
- package/dist/api-test/config.js.map +1 -0
- package/dist/api-test/db-query-cli.d.ts +51 -0
- package/dist/api-test/db-query-cli.d.ts.map +1 -0
- package/dist/api-test/db-query-cli.js +119 -0
- package/dist/api-test/db-query-cli.js.map +1 -0
- package/dist/api-test/enhance-prepare.d.ts +111 -0
- package/dist/api-test/enhance-prepare.d.ts.map +1 -0
- package/dist/api-test/enhance-prepare.js +425 -0
- package/dist/api-test/enhance-prepare.js.map +1 -0
- package/dist/api-test/enhance-write.d.ts +28 -0
- package/dist/api-test/enhance-write.d.ts.map +1 -0
- package/dist/api-test/enhance-write.js +145 -0
- package/dist/api-test/enhance-write.js.map +1 -0
- package/dist/api-test/errors.d.ts +48 -0
- package/dist/api-test/errors.d.ts.map +1 -0
- package/dist/api-test/errors.js +76 -0
- package/dist/api-test/errors.js.map +1 -0
- package/dist/api-test/field-extractor.d.ts +98 -0
- package/dist/api-test/field-extractor.d.ts.map +1 -0
- package/dist/api-test/field-extractor.js +327 -0
- package/dist/api-test/field-extractor.js.map +1 -0
- package/dist/api-test/impl-finder.d.ts +37 -0
- package/dist/api-test/impl-finder.d.ts.map +1 -0
- package/dist/api-test/impl-finder.js +54 -0
- package/dist/api-test/impl-finder.js.map +1 -0
- package/dist/api-test/index.d.ts +41 -0
- package/dist/api-test/index.d.ts.map +1 -0
- package/dist/api-test/index.js +124 -0
- package/dist/api-test/index.js.map +1 -0
- package/dist/api-test/java-parser.d.ts +89 -0
- package/dist/api-test/java-parser.d.ts.map +1 -0
- package/dist/api-test/java-parser.js +508 -0
- package/dist/api-test/java-parser.js.map +1 -0
- package/dist/api-test/md-writer.d.ts +49 -0
- package/dist/api-test/md-writer.d.ts.map +1 -0
- package/dist/api-test/md-writer.js +202 -0
- package/dist/api-test/md-writer.js.map +1 -0
- package/dist/api-test/parser-httpservice.d.ts +91 -0
- package/dist/api-test/parser-httpservice.d.ts.map +1 -0
- package/dist/api-test/parser-httpservice.js +271 -0
- package/dist/api-test/parser-httpservice.js.map +1 -0
- package/dist/api-test/report.d.ts +188 -0
- package/dist/api-test/report.d.ts.map +1 -0
- package/dist/api-test/report.js +522 -0
- package/dist/api-test/report.js.map +1 -0
- package/dist/api-test/snapshot.d.ts +26 -0
- package/dist/api-test/snapshot.d.ts.map +1 -0
- package/dist/api-test/snapshot.js +150 -0
- package/dist/api-test/snapshot.js.map +1 -0
- package/dist/api-test/test-history.d.ts +48 -0
- package/dist/api-test/test-history.d.ts.map +1 -0
- package/dist/api-test/test-history.js +122 -0
- package/dist/api-test/test-history.js.map +1 -0
- package/dist/api-test/types.d.ts +174 -0
- package/dist/api-test/types.d.ts.map +1 -0
- package/dist/api-test/types.js +13 -0
- package/dist/api-test/types.js.map +1 -0
- package/dist/api-test/verify-prepare.d.ts +30 -0
- package/dist/api-test/verify-prepare.d.ts.map +1 -0
- package/dist/api-test/verify-prepare.js +150 -0
- package/dist/api-test/verify-prepare.js.map +1 -0
- package/dist/api-test/verify-write.d.ts +31 -0
- package/dist/api-test/verify-write.d.ts.map +1 -0
- package/dist/api-test/verify-write.js +159 -0
- package/dist/api-test/verify-write.js.map +1 -0
- package/dist/dbquery/dump-schema.d.ts +46 -0
- package/dist/dbquery/dump-schema.d.ts.map +1 -0
- package/dist/dbquery/dump-schema.js +379 -0
- package/dist/dbquery/dump-schema.js.map +1 -0
- package/dist/installer/targets/claude.d.ts +15 -0
- package/dist/installer/targets/claude.d.ts.map +1 -1
- package/dist/installer/targets/claude.js +53 -0
- package/dist/installer/targets/claude.js.map +1 -1
- package/package.json +1 -1
- package/scripts/agent-eval/block-cgraphx-and-gitnexus-cli-hook.sh +0 -43
- package/scripts/agent-eval/block-cgraphx-cli-hook.sh +0 -32
- package/scripts/agent-eval/block-cgraphx-cli-settings.json +0 -16
- package/scripts/agent-eval/cli-vs-mcp-3arm.sh +0 -121
- package/scripts/agent-eval/multi-tool-eval.sh +0 -171
- package/scripts/agent-eval/parse-cli-vs-mcp.mjs +0 -232
- package/scripts/agent-eval/parse-multi-tool.mjs +0 -242
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{"interface": "GET /api/v1/users/:id", "http_status": 200, "assertions": [{"name": "status is 200", "passed": true, "expected": 200, "actual": 200}, {"name": "response has id", "passed": true, "expected": "property id", "actual": "id=12345"}, {"name": "id is number", "passed": true, "expected": "number", "actual": 12345}], "db_verification": {"required": false, "conclusion": "not_required", "queries": [], "expected": null, "actual": null, "error": null}, "final_status": "通过", "duration_ms": 239}
|
|
2
|
+
{"interface": "POST /api/v1/users", "http_status": 201, "assertions": [{"name": "status is 201", "passed": true, "expected": 201, "actual": 201}, {"name": "response has id", "passed": true, "expected": "property id", "actual": "id=12346"}], "db_verification": {"required": true, "conclusion": "通过", "queries": ["SELECT id, name, email FROM users WHERE id = 12346"], "expected": "新增一行 name=测试用户 email=test@example.com", "actual": "新增一行 id=12346 name=测试用户 email=test@example.com", "error": null}, "final_status": "通过", "duration_ms": 512}
|
|
3
|
+
{"interface": "PUT /api/v1/users/:id", "http_status": 200, "assertions": [{"name": "status is 200", "passed": true, "expected": 200, "actual": 200}], "db_verification": {"required": true, "conclusion": "失败", "queries": ["SELECT name FROM users WHERE id = 12345"], "expected": "name 更新为 新名字", "actual": "name 仍为 旧名字", "error": null}, "final_status": "失败-DB副作用", "duration_ms": 480}
|
|
4
|
+
{"interface": "GET /api/v1/orders/:id", "http_status": 404, "assertions": [], "db_verification": {"required": false, "conclusion": "not_required", "queries": [], "expected": null, "actual": null, "error": null}, "final_status": "失败-HTTP", "duration_ms": 120}
|
|
5
|
+
{"interface": "POST /api/v1/users (db-query failed)", "http_status": 201, "assertions": [{"name": "status is 201", "passed": true, "expected": 201, "actual": 201}], "db_verification": {"required": true, "conclusion": "无法核实", "queries": [], "expected": "新增一行", "actual": null, "error": "db-query 连接失败: ConnectionFailedError"}, "final_status": "失败-DB副作用", "duration_ms": 380}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# R3 跑测试规范
|
|
2
|
+
|
|
3
|
+
## bru run 命令
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
bru run docs/bruno/<服务>/<接口名>/ --env local --output <临时 JSON 路径> -r
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
### 参数说明
|
|
10
|
+
|
|
11
|
+
| 参数 | 说明 |
|
|
12
|
+
|---|---|
|
|
13
|
+
| 路径参数 | R1 清单涉及的接口目录(从 api-spec §5 取),不是全项目 `docs/bruno/` |
|
|
14
|
+
| `--env local` | 使用 `docs/bruno/environments/local.bru` 的变量(用户切换时透传 `--env staging` / `--env production`) |
|
|
15
|
+
| `--output <path>` | JSON 中间结果输出路径(临时,跑完即丢,不归档) |
|
|
16
|
+
| `-r` | 递归跑目录下所有 .bru |
|
|
17
|
+
|
|
18
|
+
### 跑哪些接口
|
|
19
|
+
|
|
20
|
+
**只跑 R1 清单涉及的接口目录**,不是全项目 `docs/bruno/`。
|
|
21
|
+
|
|
22
|
+
理由:用户指定需求或接口后,范围已锁定;跑全项目是另一个场景(全量回归),用户应自行 `bru run docs/bruno/ -r`,不归本 skill 管。
|
|
23
|
+
|
|
24
|
+
### 多接口目录的处理
|
|
25
|
+
|
|
26
|
+
R1 清单可能涉及多个接口目录(如 `getUser/` + `createUser/` + `common/login/`)。两种跑法:
|
|
27
|
+
|
|
28
|
+
- **分批跑**:每个接口目录单独 `bru run`,结果汇总(更细粒度,易定位崩溃)
|
|
29
|
+
- **合并跑**:把所有路径作为参数一次跑(bru run 支持多路径参数)
|
|
30
|
+
|
|
31
|
+
推荐**分批跑**——某个接口目录崩溃时不影响其他接口,且日志更清晰。
|
|
32
|
+
|
|
33
|
+
## 失败处理
|
|
34
|
+
|
|
35
|
+
### 单接口失败(bru run 正常返回,但某些接口 HTTP 错或断言失败)
|
|
36
|
+
|
|
37
|
+
不算崩溃,继续 R4。失败的接口在 JSON 中间结果里有状态,汇总到 R5 报告。
|
|
38
|
+
|
|
39
|
+
### bru run 整体崩溃(进程退出非 0,非单接口失败)
|
|
40
|
+
|
|
41
|
+
报"测试执行器异常" + 输出 bru 原始 stderr,**不继续 R4**。
|
|
42
|
+
|
|
43
|
+
崩溃常见原因:
|
|
44
|
+
- bruno CLI 版本 bug
|
|
45
|
+
- .bru 文件语法错(write-api 生成的 .bru 不符合 bruno-lang v2)
|
|
46
|
+
- 环境配置错(env 文件读不了)
|
|
47
|
+
|
|
48
|
+
崩溃时不继续 R4——继续也没意义(JSON 中间结果可能不完整);让用户判断是修 .bru、调 bruno 版本,还是回 write-api 重新生成。
|
|
49
|
+
|
|
50
|
+
## JSON 中间结果
|
|
51
|
+
|
|
52
|
+
`bru run --output <path>` 产出的 JSON,**临时产物,不归档**。
|
|
53
|
+
|
|
54
|
+
理由:JSON 是 bruno 的执行原始记录,字段多且对用户不友好;最终给用户看的是 R5 的 Markdown 报告 + JSONL 验证记录。JSON 跑完即丢。
|
|
55
|
+
|
|
56
|
+
## bru CLI 版本
|
|
57
|
+
|
|
58
|
+
测试工具是开源 bruno(`@usebruno/cli`),要求项目已装 bru CLI(`npm install -g @usebruno/cli` 或项目本地装)。
|
|
59
|
+
|
|
60
|
+
若 bru 命令不存在 → 报"未找到 bru CLI,请先装 `npm install -g @usebruno/cli`"并退出。
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# R4 数据库副作用核实规范
|
|
2
|
+
|
|
3
|
+
## 适用范围
|
|
4
|
+
|
|
5
|
+
**仅对写接口执行**(POST / PUT / DELETE / PATCH)。
|
|
6
|
+
|
|
7
|
+
查询接口(GET)跳过 R4,直接进 R5。
|
|
8
|
+
|
|
9
|
+
R1 清单里若没有写接口,**整个 R4 跳过**,直接 R5。
|
|
10
|
+
|
|
11
|
+
## AI 核实 prompt 指引
|
|
12
|
+
|
|
13
|
+
### 输入
|
|
14
|
+
|
|
15
|
+
每个写接口的每个跑过的场景,AI 核实时读:
|
|
16
|
+
|
|
17
|
+
- 写接口的 `.bru` — 含 docs 段业务说明 + tests 段 DB 副作用预期注释(write-api S3 写的)
|
|
18
|
+
- 跑测试后的响应 — R3 JSON 中间结果里的响应体
|
|
19
|
+
- 接口语义 — 从 api-spec §2 或代码拿(预期应该写什么)
|
|
20
|
+
- DB 状态 — 通过 `db-query` 查实际数据
|
|
21
|
+
|
|
22
|
+
### AI 动作
|
|
23
|
+
|
|
24
|
+
按以下步骤核实:
|
|
25
|
+
|
|
26
|
+
1. **确定查哪些表 / 哪些字段** — 根据 .bru tests 段的 DB 预期注释 + 接口语义
|
|
27
|
+
- 新增接口 → 查主表是否有新行
|
|
28
|
+
- 更新接口 → 查字段是否变化
|
|
29
|
+
- 删除接口 → 查记录是否消失
|
|
30
|
+
- 关联表 → 同步查(如创建用户后查 user_profile 是否同步)
|
|
31
|
+
|
|
32
|
+
2. **执行查询** — 用 `db-query` 跑 SQL,只读查询
|
|
33
|
+
|
|
34
|
+
3. **比对预期 vs 实际**
|
|
35
|
+
- 预期:接口语义说应该写什么(.bru tests 段 DB 预期注释)
|
|
36
|
+
- 实际:DB 里真的写了什么
|
|
37
|
+
|
|
38
|
+
4. **给结论**
|
|
39
|
+
- **数据写对** — DB 数据符合预期
|
|
40
|
+
- **数据写错** — 标注差异(如"预期 name=测试用户,实际 name=旧名字")
|
|
41
|
+
- **无法核实** — db-query 失败或语义不清
|
|
42
|
+
|
|
43
|
+
### 输出
|
|
44
|
+
|
|
45
|
+
每个写接口的每个跑过场景,输出一条 JSON,写入 `<文件前缀>-测试验证.jsonl`(字段格式见 `report-format.md` § JSONL 字段)。
|
|
46
|
+
|
|
47
|
+
## 失败处理
|
|
48
|
+
|
|
49
|
+
| 情况 | 处理 |
|
|
50
|
+
|---|---|
|
|
51
|
+
| HTTP 通但 DB 数据错 | 最终状态记 `失败-DB副作用`,JSONL 记录预期 vs 实际差异 |
|
|
52
|
+
| db-query 连接失败 / 查询超时 | 该接口记"无法核实" + 状态 `失败-DB副作用`,**不阻塞其他接口** |
|
|
53
|
+
| .bru tests 段无 DB 预期注释 | AI 根据接口语义自行推断预期;不能推断时记"无法核实" |
|
|
54
|
+
| 同一接口多场景 | 每场景独立核实,独立记 JSONL |
|
|
55
|
+
|
|
56
|
+
**不阻塞原则**:R4 单接口核实失败不能拖垮其他接口。一个接口 DB 错或 db-query 挂,其他接口继续核实。
|
|
57
|
+
|
|
58
|
+
## 跨步骤约束
|
|
59
|
+
|
|
60
|
+
### db-query 不可用时的降级
|
|
61
|
+
|
|
62
|
+
| 项目状态 | R4 行为 |
|
|
63
|
+
|---|---|
|
|
64
|
+
| 未配置 db-query profile | 所有写接口标"无法核实" + 状态 `失败-DB副作用`;在报告 §3 失败分类标注"项目未配置 db-query,写接口 DB 核实不可用" |
|
|
65
|
+
| db-query 配置错(连接失败) | 同上 |
|
|
66
|
+
|
|
67
|
+
降级时仍跑 R3 和 R5,只是 R4 全部标"无法核实";用户后续配置 db-query 后重跑 `/run-api-test` 补核实。
|
|
68
|
+
|
|
69
|
+
## 与 write-api 的契约
|
|
70
|
+
|
|
71
|
+
write-api S3 生成 .bru 时,在 tests 段写 DB 副作用预期注释(格式见 `../write-api/references/bru-format.md`),形如:
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
tests {
|
|
75
|
+
...
|
|
76
|
+
# DB 预期:users 表新增一行,name=测试用户,email=test@example.com
|
|
77
|
+
# DB 预期:user_profile 表同步新增一行,user_id=本次返回的 id
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
R4 AI 读这些注释作为核实预期。注释越清晰,R4 核实越准;若 write-api 没写注释,AI 退化为从接口语义自行推断,精度下降。
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# R5 测试报告规范
|
|
2
|
+
|
|
3
|
+
## 产物(两类)
|
|
4
|
+
|
|
5
|
+
| 产物 | 路径 | 用途 |
|
|
6
|
+
|---|---|---|
|
|
7
|
+
| Markdown 报告 | `docs/features/<feature-id>/<文件前缀>-测试报告.md` | 给人看:汇总 + 逐接口结果 + 失败分类 + DB 核实小结 + 下一步建议 |
|
|
8
|
+
| JSONL 验证记录 | `docs/features/<feature-id>/<文件前缀>-测试验证.jsonl` | AI 逐接口 DB 验证记录,供下游 skill 程序化处理 |
|
|
9
|
+
|
|
10
|
+
**JSON 中间结果**(R3 `bru run --output` 产的)临时,**不归档**——跑完即丢。
|
|
11
|
+
|
|
12
|
+
## 报告归属规则
|
|
13
|
+
|
|
14
|
+
**报告永远归用户触发时指定的需求目录**,即使测试涉及的接口关联多个 feature,也不混到其他 feature。
|
|
15
|
+
|
|
16
|
+
例:接口 `qryCrm2ProductDetail` 关联需求 A + B;用户指定测需求 B → 报告归 `docs/features/B/`;即使该接口的 .bru 数据可能是 A 时生成的。
|
|
17
|
+
|
|
18
|
+
## Markdown 报告章节
|
|
19
|
+
|
|
20
|
+
完整骨架见 `assets/template-test-report.md`。AI 生成时按以下章节填:
|
|
21
|
+
|
|
22
|
+
### §1. 汇总
|
|
23
|
+
|
|
24
|
+
| 指标 | 值 |
|
|
25
|
+
|---|---|
|
|
26
|
+
| 总接口数 | N |
|
|
27
|
+
| 通过 | N |
|
|
28
|
+
| 失败 | N |
|
|
29
|
+
| 跳过 | N |
|
|
30
|
+
| 总耗时 | ms |
|
|
31
|
+
| 通过率 | % |
|
|
32
|
+
|
|
33
|
+
### §2. 逐接口结果
|
|
34
|
+
|
|
35
|
+
| 方法 | 路径 | 场景 | 状态 | HTTP | 断言 | DB 核实 | 耗时(ms) |
|
|
36
|
+
|---|---|---|---|---|---|---|---|
|
|
37
|
+
|
|
38
|
+
- 查询接口的 DB 核实列填 `-`
|
|
39
|
+
- 写接口填 通过 / 失败 / 未核实
|
|
40
|
+
|
|
41
|
+
### §3. 失败原因分类
|
|
42
|
+
|
|
43
|
+
按状态枚举分组,每组列具体接口 + 预期 vs 实际 + 可能原因 + 建议下一步。
|
|
44
|
+
|
|
45
|
+
### §4. 写接口 DB 核实小结
|
|
46
|
+
|
|
47
|
+
| 接口 | 核实结论 | 查询表 | 预期 | 实际 |
|
|
48
|
+
|
|
49
|
+
仅在本次有写接口时填。
|
|
50
|
+
|
|
51
|
+
### §5. 下一步建议
|
|
52
|
+
|
|
53
|
+
按失败类型给建议,不自动调下游 skill:
|
|
54
|
+
|
|
55
|
+
- 失败-DB副作用 → 疑似代码 bug,走 `/implementation`
|
|
56
|
+
- 失败-断言 → 确认是代码 bug 还是断言写错
|
|
57
|
+
- 失败-HTTP → 确认路由注册
|
|
58
|
+
|
|
59
|
+
### §6. 产物清单
|
|
60
|
+
|
|
61
|
+
固定四项:测试规格、.bru collection、Markdown 报告(本文件)、JSONL 验证记录。
|
|
62
|
+
|
|
63
|
+
## JSONL 字段
|
|
64
|
+
|
|
65
|
+
每行一个 JSON,逐接口(每场景)一条。字段:
|
|
66
|
+
|
|
67
|
+
| 字段 | 类型 | 说明 |
|
|
68
|
+
|---|---|---|
|
|
69
|
+
| `interface` | string | 方法 + 路径(如 `GET /api/v1/users/:id`) |
|
|
70
|
+
| `scenario` | string | 场景名(如 `正常` / `缺prodInstId`) |
|
|
71
|
+
| `http_status` | number | HTTP 状态码 |
|
|
72
|
+
| `assertions` | array | 断言结果:[{name, passed, expected, actual}] |
|
|
73
|
+
| `db_verification` | object | {required: bool, conclusion: "通过"/"失败"/"无法核实"/"not_required", queries: [], expected, actual, error} |
|
|
74
|
+
| `final_status` | string | 状态枚举(见下方) |
|
|
75
|
+
| `duration_ms` | number | 耗时 |
|
|
76
|
+
|
|
77
|
+
查询接口 `db_verification.required = false, conclusion = "not_required"`。
|
|
78
|
+
|
|
79
|
+
完整示例见 `assets/template-test-verify.jsonl`。
|
|
80
|
+
|
|
81
|
+
## 状态枚举
|
|
82
|
+
|
|
83
|
+
报告 §2 / §3 / JSONL `final_status` 必须用以下枚举值:
|
|
84
|
+
|
|
85
|
+
| 状态 | 含义 |
|
|
86
|
+
|---|---|
|
|
87
|
+
| `通过` | HTTP 通 + 断言通 + (写接口)DB 核实通 |
|
|
88
|
+
| `失败-断言` | HTTP 通但断言失败 |
|
|
89
|
+
| `失败-DB副作用` | HTTP 通 + 断言通,但 DB 数据不符合预期 |
|
|
90
|
+
| `失败-HTTP` | 4xx / 5xx |
|
|
91
|
+
| `失败-连接` | 超时 / connection refused(仅在服务就绪后仍失败时记) |
|
|
92
|
+
| `跳过` | skill 主动跳过(如 .bru 缺失、环境降级) |
|
|
93
|
+
|
|
94
|
+
**服务未就绪导致的暂停不记入报告,不算失败**(服务未起时 skill 在 R2 暂停,根本没进 R3)。
|
|
95
|
+
|
|
96
|
+
## JSON 中间结果处理
|
|
97
|
+
|
|
98
|
+
R3 的 `bru run --output <path>` 产的 JSON:
|
|
99
|
+
|
|
100
|
+
- 跑完 R3 后,R4 / R5 读它做核实和汇总
|
|
101
|
+
- R5 完成后**立即丢弃**(skill 删除临时文件,或放系统临时目录自动清理)
|
|
102
|
+
- 不归档到 `docs/features/<feature-id>/`
|
|
103
|
+
|
|
104
|
+
理由:JSON 是 bruno 的原始执行记录,字段多且对用户不友好;最终给用户看的是 Markdown 报告 + JSONL 验证记录。保留 JSON 会造成"两份真相"混淆。
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# R2 服务就绪检测规范
|
|
2
|
+
|
|
3
|
+
## 两种检测策略(任一通过即就绪)
|
|
4
|
+
|
|
5
|
+
按以下优先级检测,**任一通过即视为就绪**:
|
|
6
|
+
|
|
7
|
+
1. **测试规格声明的服务地址** — `<文件前缀>-api-spec.md` §1 接口清单声明的"服务地址"(由 write-api S2 生成)能 TCP 连通
|
|
8
|
+
2. **bruno env 的 baseUrl** — `docs/bruno/environments/local.bru` 里的 `baseUrl`(或对应服务端口变量)能 TCP 连通
|
|
9
|
+
|
|
10
|
+
两者都失败 → 视为未就绪,进入暂停等待。
|
|
11
|
+
|
|
12
|
+
## TCP 连通超时
|
|
13
|
+
|
|
14
|
+
默认 **3 秒**。
|
|
15
|
+
|
|
16
|
+
理由:本地服务通常毫秒级响应;3 秒连不上基本就是没启动。超时阈值不要太长,避免用户等太久才发现服务没起。
|
|
17
|
+
|
|
18
|
+
## env 文件缺失处理
|
|
19
|
+
|
|
20
|
+
`docs/bruno/environments/local.bru` 不存在 → **报错退出,不自动生成**。
|
|
21
|
+
|
|
22
|
+
报错信息:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
环境配置缺失:docs/bruno/environments/local.bru 不存在。
|
|
26
|
+
本 skill(run-api-test)不负责生成环境配置,请先跑 /write-api 生成骨架并填好 secret。
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**为什么不自动生成**:环境配置(尤其 secret 字段如 token、staffcode)属于 write-api 的职责范围;run-api-test 自动生成会越界,且 AI 无法知道用户实际的 token 值。
|
|
30
|
+
|
|
31
|
+
## 服务未就绪处理
|
|
32
|
+
|
|
33
|
+
检测失败 → skill 暂停,提示:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
本地服务未就绪(TCP 连接失败)。
|
|
37
|
+
请启动本地服务后回车继续,或 Ctrl+C 取消。
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**不**自动重试、**不**自动跳过、**不**把 connection refused 当失败记入报告。
|
|
41
|
+
|
|
42
|
+
**为什么这样设计**:
|
|
43
|
+
- 自动重试 → 服务起不来时 skill 卡死循环
|
|
44
|
+
- 自动跳过 → 跑出大量假失败,污染报告
|
|
45
|
+
- 当失败记入 → 报告失真,看不出是真接口问题还是服务没起
|
|
46
|
+
|
|
47
|
+
服务就绪后用户回车,继续 R3。
|
|
48
|
+
|
|
49
|
+
## 就绪后继续
|
|
50
|
+
|
|
51
|
+
任一策略 TCP 连通 → 视为就绪,继续 R3 跑测试。
|
|
52
|
+
|
|
53
|
+
## 环境切换
|
|
54
|
+
|
|
55
|
+
默认 `local` 环境(用 `environments/local.bru`)。
|
|
56
|
+
|
|
57
|
+
用户调用 `/run-api-test --env staging` 或 `--env production` 时:
|
|
58
|
+
- 透传给 `bru run --env staging` / `--env production`
|
|
59
|
+
- 服务就绪检测改读对应环境的 `baseUrl` 变量
|
|
60
|
+
|
|
61
|
+
切换环境不影响 .bru 清单(R1 已锁定),只影响 env 变量注入。
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# R1 确定测试范围规范
|
|
2
|
+
|
|
3
|
+
## 输入
|
|
4
|
+
|
|
5
|
+
R1 的输入由 SKILL.md 触发逻辑(三分支)锁定一个 feature-id 后,从该 feature 的测试规格文档拿:
|
|
6
|
+
|
|
7
|
+
- 路径:`docs/features/<feature-id>/<文件前缀>-api-spec.md`
|
|
8
|
+
- §1 接口清单:方法 + 路径 + 是否写接口
|
|
9
|
+
- §2 测试场景:每接口要测的场景名(正常/缺字段/不存在等)
|
|
10
|
+
- §5 接口映射:场景 → 接口 → .bru 文件路径
|
|
11
|
+
|
|
12
|
+
## 交叉校验 .bru 存在
|
|
13
|
+
|
|
14
|
+
**必须做**:遍历 §5 接口映射列出的所有 .bru 路径,逐个检查文件是否存在。
|
|
15
|
+
|
|
16
|
+
| 情况 | 处理 |
|
|
17
|
+
|---|---|
|
|
18
|
+
| 全部存在 | 进入用户确认环节 |
|
|
19
|
+
| 部分缺失 | 报"需求 X 接口 Y 场景 Z 的 .bru 缺失,请先跑 /write-api"并退出 |
|
|
20
|
+
| 全部缺失(该 feature 没跑过 write-api) | 报"需求 X 无测试规格或 .bru 全缺失,请先跑 /write-api"并退出 |
|
|
21
|
+
|
|
22
|
+
**理由**:跑测试前确保 .bru 都在,避免跑到一半才发现缺文件,浪费已跑的测试时间。
|
|
23
|
+
|
|
24
|
+
## 用户确认环节(不能省)
|
|
25
|
+
|
|
26
|
+
显示测试范围给用户,等用户确认后继续。
|
|
27
|
+
|
|
28
|
+
显示内容:
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
本次测试范围:
|
|
32
|
+
- 需求:<feature-id>
|
|
33
|
+
- 接口数:N
|
|
34
|
+
- 场景数:M(查询 K1 个 + 写 K2 个)
|
|
35
|
+
- 含写接口:是 / 否(若是,会做 DB 副作用核实)
|
|
36
|
+
- .bru 清单:(列出涉及的 docs/bruno/<服务>/<接口名>/ 目录)
|
|
37
|
+
|
|
38
|
+
确认后回车继续,或 Ctrl+C 取消。
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**为什么不能省**:AI 反查"接口关联哪些需求"、读 api-spec 拿场景等过程中可能理解偏差;用户确认环节让用户兜底,避免跑错需求或跑错接口集合。
|
|
42
|
+
|
|
43
|
+
## 输出
|
|
44
|
+
|
|
45
|
+
R1 输出**本次跑的 .bru 清单**(路径列表),供 R3 bru run 用。清单形如:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
docs/bruno/user-service/getUser/正常.bru
|
|
49
|
+
docs/bruno/user-service/getUser/不存在.bru
|
|
50
|
+
docs/bruno/user-service/createUser/正常.bru
|
|
51
|
+
docs/bruno/common/login/正常.bru
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
清单是 R3 bru run 的输入,清单决定跑哪些接口目录。
|
|
55
|
+
|
|
56
|
+
## 边界情况
|
|
57
|
+
|
|
58
|
+
| 情况 | 处理 |
|
|
59
|
+
|---|---|
|
|
60
|
+
| 用户指定需求但 api-spec.md 不存在 | 报"需求 X 无测试规格,请先跑 /write-api"并退出 |
|
|
61
|
+
| 用户指定接口但接口目录不存在 | 报"接口 Y 无 .bru,请先跑 /write-api"并退出 |
|
|
62
|
+
| 用户指定接口但扫目录发现 0 个需求测过 | 提示"未在 docs/bruno/ 下找到测过接口 Y 的需求,请先跑 /write-api" |
|
|
63
|
+
| api-spec §5 列出的 .bru 实际不存在 | 报"需求 X 接口 Y 场景 Z 的 .bru 缺失,请先跑 /write-api"并退出 |
|
|
64
|
+
| 用户确认环节用户取消 | 退出,不进入 R2 |
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: write-api
|
|
3
|
+
description: 基于需求生成 bruno 测试接口(.bru + 测试规格 + 环境配置)。流程:识别接口范围(用户显式给 / spec 接口章节 / AI 读 spec 理解)→ 生成测试规格文档 → 单次 AI 调用生成 .bru(含真实参数 + 内嵌断言)→ 首次接入时生成 bruno.json + environments/*.bru 骨架。产物:测试规格随 feature 走;.bru collection 按 <服务>/<需求前缀>/<接口名>/<场景> 组织在 docs/bruno/(按需求隔离,跨需求不覆盖);environments 统一管理。本 skill 不跑 bru run、不核实 DB、不出报告——那是 /run-api-test 的职责。不调 write-api-doc、不自动修代码、不引入程序化配置文件(微服务/通用接口识别由 AI 判断)。Use when 用户要求生成测试接口 / 写接口测试 / 准备 bruno 测试 / 帮需求补接口 / 免去手动录接口。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Write API
|
|
7
|
+
|
|
8
|
+
## 定位
|
|
9
|
+
|
|
10
|
+
造弹药 skill:基于需求生成 bruno 测试接口的"原料"——测试规格 + .bru + 多环境配置。跑测试 + DB 核实 + 出报告由 `/run-api-test` 接管,本 skill 不做。
|
|
11
|
+
|
|
12
|
+
## HARD-GATE
|
|
13
|
+
|
|
14
|
+
- 不重新定义 spec 已锁定的接口契约——发现 spec 与代码现实不符,标注【待确认】而不是自行解释
|
|
15
|
+
- 不编造未在代码或 spec 中体现的接口、参数、响应字段、断言
|
|
16
|
+
- 编写的请求地址禁止使用 baseUrl,因为一个项目会有很多服务, 必须使用服务名称作为地址变量(如 `so-assist: http://127.0.0.1:8087`)
|
|
17
|
+
|
|
18
|
+
## Trigger
|
|
19
|
+
|
|
20
|
+
**使用此 skill 当**:
|
|
21
|
+
- 用户要求"生成测试接口""写接口测试""准备 bruno 测试""write-api"
|
|
22
|
+
- 用户在 `/implementation` 或 `/subagent-implement` 完成编码后,触发本 skill 准备测试接口
|
|
23
|
+
- 用户想为某个需求生成 / 补接口,免去手动录
|
|
24
|
+
|
|
25
|
+
**不要使用此 skill 当**:
|
|
26
|
+
- 跑接口测试 → 用 `/run-api-test`
|
|
27
|
+
- 写 PRD / spec / plan → 用 `/write-prd` / `/write-spec` / `/write-plan`
|
|
28
|
+
- 写 HTML 接口文档 → 用 `/write-api-doc`
|
|
29
|
+
- 探索陌生项目 → 用 `/code-impact-init`
|
|
30
|
+
- 查代码调用关系 → 用 `/cgraphx` 或 `codegraph_explore` MCP
|
|
31
|
+
|
|
32
|
+
## 与既有 skill 边界
|
|
33
|
+
|
|
34
|
+
| skill | 关系 | 说明 |
|
|
35
|
+
|---|---|---|
|
|
36
|
+
| `run-api-test` | 下游 + 独立 | 消费本 skill 产的 .bru + 测试规格跑测试;本 skill 不调它,跑测试由用户显式触发;同一份 .bru 可被多次 run-api-test 复用 |
|
|
37
|
+
| `cgraphx` / `codegraph_explore` | 复用 | S1 定位 handler、S3 提取参数定义时调用 |
|
|
38
|
+
| `db-query` | 复用 | S3 查真实测试数据;DB 副作用核实由 `/run-api-test` R4 做 |
|
|
39
|
+
| `write-api-doc` | 独立并列 | 不互相调用;本 skill 产 .bru + 测试规格,write-api-doc 产 HTML 接口文档 |
|
|
40
|
+
| `implementation` / `subagent-implement` | 上游 | 编码阶段,跑完触发本 skill |
|
|
41
|
+
| `code-impact-docgen` | 独立 | 自测后产设计文档 |
|
|
42
|
+
|
|
43
|
+
## 依赖
|
|
44
|
+
|
|
45
|
+
- feature 编码已完成(`/implementation` 或 `/subagent-implement` 跑完)
|
|
46
|
+
- `docs/features/<feature-id>/<文件前缀>-spec.md` 存在(S1 优先级 2 要用)
|
|
47
|
+
- 项目已接入 cgraphx 索引(S3 定位 handler)—— 未接入则 S3 降级,见 `references/ai-prompts.md` § 降级处理
|
|
48
|
+
- 项目已配置 db-query profile(S3 查真实数据)—— 未配置则 S3 降级
|
|
49
|
+
|
|
50
|
+
## feature-id 与文件前缀规则
|
|
51
|
+
|
|
52
|
+
复用既有规则(同 `/write-prd` / `/write-spec` / `/write-plan` / `/write-api-doc` 的算法):
|
|
53
|
+
|
|
54
|
+
- feature-id 格式:`YYYY-MM-DD-[业务ID-]<标题>`
|
|
55
|
+
- 文件前缀:有业务ID = `<业务ID>-<标题>`,无业务ID = `<标题>`
|
|
56
|
+
- 标题段允许中文、英文或混合,**不得**对中文做英文 slug 转换
|
|
57
|
+
- 文件名不得包含 `/`、`:`、`*`、`?`、`"`、`<`、`>`、`|`
|
|
58
|
+
|
|
59
|
+
产物文件名:
|
|
60
|
+
- 测试规格:`docs/features/<feature-id>/<文件前缀>-api-spec.md`
|
|
61
|
+
- .bru:`docs/bruno/<服务>/<文件前缀>/<接口名>/<场景>.bru`(按需求隔离,见 `references/collection-layout.md`)
|
|
62
|
+
- bruno.json + environments:见 `references/environment-setup.md`
|
|
63
|
+
|
|
64
|
+
测试报告 / JSONL 不由本 skill 产——`/run-api-test` 跑完后产,落 `docs/features/<feature-id>/`。
|
|
65
|
+
|
|
66
|
+
## 工作流
|
|
67
|
+
|
|
68
|
+
按 S1-S4 顺序执行,每步的规范细节在对应 reference 文件。
|
|
69
|
+
|
|
70
|
+
### S1. 确认接口范围
|
|
71
|
+
|
|
72
|
+
- **前置**:用户调用 `/write-api`,提供需求(feature-id / spec / 需求名)
|
|
73
|
+
- **行为**:按 `references/interface-scope.md` 识别接口范围(用户显式给 > spec 接口章节 > git diff)
|
|
74
|
+
- **无论哪种来源,接口清单必须显示给用户确认**——避免 AI 理解偏差测错接口;用户确认后才进 S2
|
|
75
|
+
- **拿到接口并用户确认** → 进 S2
|
|
76
|
+
- **拿不到** → 报错"未检测到接口范围,请显式给接口清单或确认 spec 接口章节完整"并退出,不生成任何产物
|
|
77
|
+
|
|
78
|
+
### S2. 生成测试规格文档
|
|
79
|
+
|
|
80
|
+
- **前置**:S1 接口清单已确认
|
|
81
|
+
- **行为**:按 `references/api-spec-format.md` 六节结构生成测试规格文档;AI 做微服务识别 + 通用接口判断(prompt 见 `references/ai-prompts.md` §S2),结果写入 §1 接口清单的"服务"和"通用"列
|
|
82
|
+
- **用户校正**:AI 识别结果在 §1 列出后,用户可在 S3 前校正"服务"和"通用"两列,skill 以校正后为准
|
|
83
|
+
- **结果**:落盘 `docs/features/<feature-id>/<文件前缀>-api-spec.md`
|
|
84
|
+
|
|
85
|
+
### S3. 生成 bruno 测试接口
|
|
86
|
+
|
|
87
|
+
- **前置**:S2 测试规格就绪(含用户校正后的服务/通用标注)
|
|
88
|
+
- **行为**:**单次 AI 调用**生成全部 .bru(不拆两阶段、不逐接口循环,见 `references/ai-prompts.md` §S3)
|
|
89
|
+
- .bru 格式 / 断言 / 入参 / docs 段 → `references/bru-format.md`
|
|
90
|
+
- 落盘路径 / 按需求隔离 / 根级 bruno.json → `references/collection-layout.md`
|
|
91
|
+
- 使用 db-query skill 获取基于数据库的测试数据
|
|
92
|
+
- 拿不到真实数据时 → 留 `{{var}}` 占位 + 测试规格 §3 标注"需用户手填"
|
|
93
|
+
- **AI 调用失败**(超时/限流)→ 报"AI 增强失败" + 保留 S2 测试规格,**不继续 S4**
|
|
94
|
+
- **结果**:全部 .bru 落盘到 `<服务>/<需求前缀>/<接口名>/<场景>.bru` + 根级 bruno.json 就绪
|
|
95
|
+
|
|
96
|
+
### S4. 首次接入环境准备
|
|
97
|
+
|
|
98
|
+
- **前置**:S3 .bru 已生成
|
|
99
|
+
- **行为**:按 `references/environment-setup.md` 检查并准备 bruno collection 基础设施:
|
|
100
|
+
- `bruno.json` 缺失 → 生成
|
|
101
|
+
- `environments/local.bru` 缺失 → 生成三环境骨架 + AI 填 non-secret + secret 留空 + 暂停提示用户填
|
|
102
|
+
- 已存在 → 沿用,**不重写**
|
|
103
|
+
- **结果**:基础设施就绪,用户可调 `/run-api-test` 跑测试
|
|
104
|
+
|
|
105
|
+
## 工作流结束
|
|
106
|
+
|
|
107
|
+
S4 完成后 skill 结束。**不跑 bru run、不核实 DB、不出报告**。
|
|
108
|
+
|
|
109
|
+
产物:
|
|
110
|
+
- `docs/features/<feature-id>/<文件前缀>-api-spec.md`(测试规格)
|
|
111
|
+
- `docs/bruno/<服务>/<文件前缀>/<接口名>/<场景>.bru`(测试接口,按需求隔离)
|
|
112
|
+
- `docs/bruno/bruno.json` + `docs/bruno/environments/*.bru`(首次接入生成)
|
|
113
|
+
|
|
114
|
+
## 异常速查
|
|
115
|
+
|
|
116
|
+
| 场景 | 行为 |
|
|
117
|
+
|---|---|
|
|
118
|
+
| 无新增接口 | 报错退出,不生成空产物 |
|
|
119
|
+
| 接口范围三种来源都拿不到 | 报错退出 |
|
|
120
|
+
| AI 拿不到真实测试数据 | 留 `{{var}}` 占位 + 测试规格标注"需用户手填",继续跑能跑的部分 |
|
|
121
|
+
| AI 调用失败 | 报"AI 增强失败" + 保留测试规格,不继续 S4 |
|
|
122
|
+
| 同需求重复触发 write-api | 覆盖该需求的 .bru + 覆盖测试规格(数据从当前需求 spec + DB 重新取) |
|
|
123
|
+
| 跨需求同接口同场景 | 各需求独立保留,不覆盖(分别在自己需求目录下) |
|
|
124
|
+
| 项目首次接入 | 自动创建 `docs/bruno/` + bruno.json + environments/ |
|
|
125
|
+
| env 文件缺失 | S4 生成骨架 + AI 填 non-secret + 暂停提示用户填 secret |
|
|
126
|
+
|
|
127
|
+
详细异常边界参考对应 reference 文件。
|
|
128
|
+
|
|
129
|
+
## 质量检查
|
|
130
|
+
|
|
131
|
+
跑完后自检:
|
|
132
|
+
- 测试规格文档落盘 feature 目录,六节齐全
|
|
133
|
+
- .bru 按 `<服务>/<需求前缀>/<接口名>/<场景>.bru` 组织,无 `collection.bru`
|
|
134
|
+
- 根级 `bruno.json` 存在;首次接入时 `environments/` + 三环境 .bru 生成,secret 留空
|
|
135
|
+
- .bru 用旧版 tests 语法(`test("name", function() { res.getStatus()/res.getBody()... })`),无 `assert` 段、无 `function onResponse`
|
|
136
|
+
- .bru 的 docs 段含业务说明(关联需求由目录层级表达,docs 段不写关联需求列表)
|
|
137
|
+
- 入参写真实值,变量化只用于环境级 / 前置动态 / 拿不到时占位
|
|
138
|
+
- header 名 / `{{var}}` 变量名大小写与项目既有 .bru 对齐
|
|
139
|
+
- 无程序化配置文件(`.services.yml` / `.config.yml`)
|
|
140
|
+
- **工作流停在 S4,没跑 bru run,没核实 DB,没出报告**
|
|
141
|
+
|
|
142
|
+
## 收尾
|
|
143
|
+
|
|
144
|
+
提示用户:
|
|
145
|
+
1. 测试规格位置(`<文件前缀>-api-spec.md`)
|
|
146
|
+
2. .bru collection 位置(`docs/bruno/<服务>/<文件前缀>/<接口名>/`)
|
|
147
|
+
3. 首次接入:bruno.json + environments/*.bru 已生成,需填 `local.bru` 的 secret 变量
|
|
148
|
+
4. 下一步:**跑 `/run-api-test` 跑测试 + 核实 DB + 出报告**
|
|
149
|
+
|
|
150
|
+
不主动调用 `/run-api-test` 或其他下游 skill。不写 knowledge 文件。不修改 spec / plan / 代码 / .bru。
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# 接口测试规格模板
|
|
2
|
+
|
|
3
|
+
适用于 feature 编码完成后,由 `write-api` skill 在 S2 生成。默认输出到 `docs/features/<feature-id>/<文件前缀>-api-spec.md`。
|
|
4
|
+
|
|
5
|
+
本模板由 AI 在 S2 填充:§1 接口清单的"服务"和"通用"列由 AI 判断(见 SKILL.md 的 S2 prompt 指引),用户可在 S3 前手动校正。
|
|
6
|
+
|
|
7
|
+
## 完整结构
|
|
8
|
+
|
|
9
|
+
```markdown
|
|
10
|
+
# 接口测试规格:<feature 标题>
|
|
11
|
+
|
|
12
|
+
> feature-id: <feature-id>
|
|
13
|
+
> 生成时间: <YYYY-MM-DD HH:MM>
|
|
14
|
+
> 关联接口集合: docs/bruno/<服务>/<文件前缀>/
|
|
15
|
+
|
|
16
|
+
## 1. 接口清单
|
|
17
|
+
|
|
18
|
+
| 方法 | 路径 | handler | 服务 | 通用 | 是否写接口 |
|
|
19
|
+
|---|---|---|---|---|---|
|
|
20
|
+
| GET | /api/v1/users/:id | UserController.getUser | user-service | no | 否 |
|
|
21
|
+
| POST | /api/v1/users | UserController.create | user-service | no | 是 |
|
|
22
|
+
| POST | /api/v1/auth/login | AuthController.login | - | yes | 是 |
|
|
23
|
+
|
|
24
|
+
- "服务"列由 AI 在 S2 判断(参考 docs/bruno/ 既有目录),无服务划分时填 "-"
|
|
25
|
+
- "通用"列由 AI 在 S2 判断(yes 表示放 docs/bruno/common/)
|
|
26
|
+
- "是否写接口"决定 S6 是否核实 DB 副作用
|
|
27
|
+
|
|
28
|
+
## 2. 测试场景
|
|
29
|
+
|
|
30
|
+
### GET /api/v1/users/:id
|
|
31
|
+
- 正常场景:存在 id,返回 200 + 用户详情
|
|
32
|
+
- 边界场景:id 不存在,返回 404
|
|
33
|
+
- 异常场景:id 格式非法,返回 400
|
|
34
|
+
|
|
35
|
+
### POST /api/v1/users
|
|
36
|
+
- 正常场景:合法参数,返回 201 + 新用户
|
|
37
|
+
- 边界场景:必填字段缺失,返回 400
|
|
38
|
+
- 异常场景:唯一约束冲突,返回 409
|
|
39
|
+
|
|
40
|
+
### POST /api/v1/auth/login
|
|
41
|
+
- 正常场景:正确账号密码,返回 200 + token
|
|
42
|
+
- 异常场景:错误密码,返回 401
|
|
43
|
+
|
|
44
|
+
## 3. 测试数据
|
|
45
|
+
|
|
46
|
+
### GET /api/v1/users/:id
|
|
47
|
+
| 场景 | 参数 | 值 | 获取方式 |
|
|
48
|
+
|---|---|---|---|
|
|
49
|
+
| 正常 | id | 12345 | DB 查询(users 表取已有 id) |
|
|
50
|
+
| 不存在 | id | 999999 | AI 推断(取不存在的 id) |
|
|
51
|
+
| 非法 | id | "abc" | AI 推断 |
|
|
52
|
+
|
|
53
|
+
### POST /api/v1/users
|
|
54
|
+
| 场景 | 参数 | 值 | 获取方式 |
|
|
55
|
+
|---|---|---|---|
|
|
56
|
+
| 正常 | name | "测试用户" | AI 推断 |
|
|
57
|
+
| 正常 | email | "test@example.com" | AI 推断 |
|
|
58
|
+
| 正常 | phone | 13800000000 | AI 推断 |
|
|
59
|
+
| 缺必填 | name | (不传) | - |
|
|
60
|
+
|
|
61
|
+
- 获取方式:代码提取 / DB 查询 / AI 推断 / 用户手填
|
|
62
|
+
- 标"用户手填"的参数:在 .bru 里留 {{var}} 占位,跑前需用户在 .bru 或 env 里填实
|
|
63
|
+
|
|
64
|
+
## 4. 数据获取方式
|
|
65
|
+
|
|
66
|
+
本 feature 测试数据来源汇总:
|
|
67
|
+
|
|
68
|
+
- **代码提取**:从 handler 源码拿默认值、必填项、参数类型
|
|
69
|
+
- **DB 查询**:通过 db-query 查 users 表取真实 id;查 inst_attr 表取真实 attr_id
|
|
70
|
+
- **AI 推断**:组装符合校验规则的测试值(手机号、邮箱格式等)
|
|
71
|
+
- **用户手填**:以下参数需用户在跑前确认或补充:
|
|
72
|
+
- {{token}}:登录 token,需先跑通用接口 POST /api/v1/auth/login 拿到
|
|
73
|
+
- {{admin_user_id}}:管理员用户 id,若 DB 无现成数据需用户指定
|
|
74
|
+
|
|
75
|
+
降级说明(若项目未接入 cgraphx / db-query,在此标注):
|
|
76
|
+
- 未接入 cgraphx:S3 用 grep + Read 兜底,参数提取精度可能下降
|
|
77
|
+
- 未配置 db-query:S3 留 {{var}} 占位,S6 DB 核实标"无法核实"
|
|
78
|
+
|
|
79
|
+
## 5. 接口映射
|
|
80
|
+
|
|
81
|
+
| 场景 | 接口 | .bru 文件路径 |
|
|
82
|
+
|---|---|---|
|
|
83
|
+
| GET /api/v1/users/:id 正常 | GET /api/v1/users/:id | docs/bruno/user-service/<文件前缀>/getUser/正常.bru |
|
|
84
|
+
| POST /api/v1/users 正常 | POST /api/v1/users | docs/bruno/user-service/<文件前缀>/createUser/正常.bru |
|
|
85
|
+
| POST /api/v1/users 缺必填 | POST /api/v1/users | docs/bruno/user-service/<文件前缀>/createUser/缺name.bru |
|
|
86
|
+
| POST /api/v1/auth/login 正常 | POST /api/v1/auth/login | docs/bruno/common/login/正常.bru |
|
|
87
|
+
|
|
88
|
+
- .bru 按服务 + 需求 + 接口组织(按需求隔离,跨需求不覆盖)
|
|
89
|
+
- 通用接口落 docs/bruno/common/<接口名>/(不绑需求)
|
|
90
|
+
|
|
91
|
+
## 6. 验收口径
|
|
92
|
+
|
|
93
|
+
什么算通过:
|
|
94
|
+
|
|
95
|
+
- 查询接口:HTTP 200 + 断言通(响应体关键字段符合预期)
|
|
96
|
+
- 写接口:HTTP 2xx + 断言通 + **DB 核实通**(数据真的写了/改了/删了,字段值正确)
|
|
97
|
+
- 通用接口:同查询/写接口规则
|
|
98
|
+
|
|
99
|
+
什么不算通过:
|
|
100
|
+
|
|
101
|
+
- HTTP 200 但断言失败 → 失败-断言
|
|
102
|
+
- HTTP 200 + 断言通但 DB 数据错 → 失败-DB副作用
|
|
103
|
+
- 4xx / 5xx → 失败-HTTP
|
|
104
|
+
- 超时 / connection refused(服务就绪后)→ 失败-连接
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## 填写说明
|
|
108
|
+
|
|
109
|
+
- AI 在 S2 生成时,§1 的"服务"和"通用"列必须填(由 AI 判断),用户可在 S3 前校正
|
|
110
|
+
- §2-§6 由 AI 根据 spec 接口章节 + 代码 + DB 数据填充
|
|
111
|
+
- §4 的"用户手填"项要与 S3 生成的 .bru 里的 `{{var}}` 占位一一对应
|
|
112
|
+
- 降级说明仅在项目未接入 cgraphx / db-query 时填,正常情况留空或删
|