源码驱动 API 全路径自动化测试
从后端源码出发,分析端点与业务分支,生成 Postman Collection,通过 Newman 执行并输出 HTML 报告。
⚡ 新手 30 秒入门
直接复制这些触发示例就能开始:
✅ 根据源码对 OrderController 做全路径 API 测试
✅ 读源码给设备管理模块生成接口自动化测试
✅ 对 UserController 做源码驱动 API 测试
✅ 给网关接口做全路径测试
一句话流程: 检查 record.md(有则读取环境信息,无则询问并写入)→ 强制校验 → 源码分析 → 用例设计(含场景匹配,等你确认)→ 生成 Collection → Newman 执行 → 输出结果并更新 record.md(HARD STOP,绝不自动修复)。
受众说明:
| 用户类型 | 如何使用 |
|---|---|
| 测试/QA 工程师 | 直接使用,全流程自动产出用例与报告,仅需在步骤 3 确认用例计划 |
| 后端开发 | 提测前自查接口行为,重点利用 throw 分支异常用例验证错误处理 |
| 初学者 | 先读"工作流总览",按步骤 1→6 顺序跟随即可,references 中均有现成示例 |
| 团队维护者 | 将产出的 Collection 纳入仓库,作为回归测试资产重复执行 |
能力边界说明
✅ 擅长处理
- 任意技术栈 API 测试:Spring Boot 按标准分层模板分析,其他框架由 AI 自主识别对应层;默认正常场景,可选全路径四维度覆盖
- 4 种认证方式:Cookie/Session、Bearer Token、HTTP Basic、API Key
- Collection 生成 + Newman 执行 + HTML 报告:含 7 个必备代码模式
⚠️ 需要素材才能做
- 完整流程:需要 baseUrl + 认证凭证;缺失时强制校验,未通过禁止继续(见步骤 1.3)
- 认证凭证:需要对应认证方式的完整信息;无法判断时询问用户
- 精确断言文本:国际化消息需提供或允许读取 messages.properties
❌ 超出范围
- 无可读源码的纯黑盒接口 → 可手工提供端点清单后复用本 Skill 的用例设计与执行部分
- 性能/压力测试 → 使用 JMeter 或 Gatling
- 前端/UI 测试 → 使用 Playwright/Selenium
工作流总览
按以下 6 步顺序执行,每步完成后再进入下一步。步骤 3 的输出需经用户确认后才能继续。步骤 5 Newman 执行完毕后为 HARD STOP——无论通过或失败,严禁进入任何修复动作,直接进入步骤 6 输出结果后终止。
Task Progress:
- [ ] 步骤1:读取/获取环境信息(record.md 优先)+ 强制校验
- [ ] 步骤2:源码分析
- [ ] 步骤3:测试用例设计(含场景匹配)→ 输出用例计划表给用户确认(修改后须再次确认)
- [ ] 步骤4:生成 Collection
- [ ] 步骤5:Newman 执行 + 报告
- [ ] 步骤6:输出结果 + 更新 record.md
步骤1:收集必要信息
1.1 环境检查
确认已安装 newman 与 newman-reporter-htmlextra:
newman --version
npm ls -g newman-reporter-htmlextra
缺失则安装:npm install -g newman newman-reporter-htmlextra
1.2 读取/获取环境信息
- 先确定输出目录(用户指定或默认
./api-tests) - 检查
<输出目录>/record.md是否存在 - 存在:直接读取其中的测试环境信息(baseUrl、认证方式、凭证字段等),跳过询问,进入 1.3 校验
- 不存在:一次性询问用户所有缺失项(baseUrl、认证方式、对应凭证字段),收集齐全后将环境信息写入 record.md(首次创建台账),进入 1.3 校验
认证方式参考(4 选 1):
| 选项 | 说明 | 需要获取的信息 | 配置参考 |
|---|---|---|---|
| Cookie/Session | 通过登录接口获取会话 Cookie | 登录地址、用户名、密码 | auth-cookie-session.md |
| Bearer Token | 使用预设的 JWT/OAuth Token | Token 值 | auth-bearer-token.md |
| HTTP Basic | 用户名密码 Base64 编码 | 用户名、密码 | auth-http-basic.md |
| API Key | 自定义 Key-Value 添加到 Header 或 Query | Key 名称、Value 值、添加位置 | auth-api-key.md |
关键差异:Cookie/Session 将"登录"作为 Collection 的第一个真实请求(依赖 Newman Cookie jar 自动携带会话);其余三种通过 Collection 级 auth 字段配置,无需登录请求。
1.3 强制校验环境信息
无论信息来自 record.md 还是用户输入,都必须逐项校验以下必填项是否已获取:
- baseUrl(非空)
- 认证方式(4 选 1 已确定)
- 对应认证方式的凭证字段完整:
- Cookie/Session → 用户名 + 密码
- Bearer Token → token 值
- HTTP Basic → 用户名 + 密码
- API Key → key 名称 + 值
任何一项缺失:禁止进入步骤 2,必须向用户询问补充,直到所有必填项齐全后才允许继续。
校验通过后将最终确认的环境信息写入/更新 record.md。
步骤2:源码分析
这是本工作流的核心差异点。详细方法论见 source-analysis-guide.md。
技术栈适配原则: 非 Spring Boot 项目由 AI 自主分析源码,提取相同目标(端点清单、错误分支、校验规则、错误→响应映射),遵守同一准确性要求,产出相同格式摘要。
Spring Boot 阅读顺序:
- Controller:端点清单(HTTP 方法 + 路径 + 参数)、请求/响应结构
- DTO/VO/Request/Response:字段定义、类型、嵌套结构
- Service(impl):业务逻辑、每一个 throw 分支(异常用例的来源)
- Validator / 校验注解:校验规则、错误消息、取值范围(参数校验用例的来源)
- ExceptionHandler:异常如何映射为响应(HTTP 状态码 + body 结构)
需要提取的关键信息:
- 端点清单:
方法 路径 → 功能 - 业务异常响应格式:例如 HTTP 200 + body
{code:500, message:"xxx"}(很多 Spring Boot 项目用统一包装返回业务错误,而非 HTTP 4xx/5xx) - 每个 Service throw 分支对应的错误消息文本(用于断言
message) - 每条校验规则的边界值(用于构造越界数据)
准确性要求(禁止臆造): 摘要中的每一项结论都必须有源码依据(具体类名/方法/注解/throw 语句),严禁臆造源码中不存在的错误消息、响应字段或校验规则;消息文本无法确定时(如动态拼接、国际化未找到对应文件),必须在摘要中显式标注"待确认",并改用 include 关键片段的宽松断言或向用户求证,不得凭猜测写精确断言。
输出:源码分析摘要
分析完成后按 source-analysis-guide.md 的「源码分析摘要模板」输出(端点清单 / 响应格式 / throw 分支 / 校验规则 / 认证),无需等待用户确认,直接进入步骤3。
步骤3:测试用例设计
基于源码分析摘要设计用例。详细规范见 testcase-design-spec.md。
3.0 场景匹配(读取 record.md 历史场景)
检查 <输出目录>/record.md 是否存在,若存在则解析其中的「测试场景记录」,与步骤 2 源码分析得到的端点清单逐一比对,产出三种结论之一:
| 匹配结论 | 处理策略 |
|---|---|
| 完全相同(端点与分支未变化) | 原地更新已有 Collection(同名文件),报告同路径覆盖写 |
| 部分相似(仅新增端点/分支/校验) | 复用同一 Collection 文件扩展用例,报告同路径覆盖写,保持一个场景一份文件 |
| 全新场景(或 record.md 不存在) | 新建 <场景名>.postman_collection.json 与 <场景名>-report.html |
匹配结论与拟复用/新建的文件路径必须写进步骤 3 的用例计划表,随用户确认一并纠正;用户不认可复用结论时可改为新建。
3.0.1 覆盖模式判定(设计用例前必须先判定)
从用户提示词识别关键词(全路径/全覆盖/全量测试),确定覆盖模式:
| 模式 | 触发条件 | 用例范围 |
|---|---|---|
| 正常场景模式(默认) | 提示词未包含上述关键词 | 仅 F0-Setup(登录/业务前置,认证必需)、F1 正常流程、F3 回读验证、F5 清理;不生成 F2 组合场景、F4 校验/业务异常及边界值用例,避免测试文件过大 |
| 全路径模式 | 提示词包含上述关键词,或用户在确认点要求切换 | 3.1 四维度全覆盖 |
两种模式下 3.2 编号分组与 3.3 顺序依赖闭环设计规则不变;步骤 2 的源码分析无论哪种模式都完整执行(throw 分支/校验规则仍需提取,供全路径模式或后续切换时使用)。
3.1 四维度覆盖(仅全路径模式)
- 正常流程:每个端点的合法输入
- 异常分支:Service 中每个 throw 分支 → 一个异常用例
- 参数校验:Validator 中每条规则 → 越界/非法值用例
- 边界值:取值范围的上下边界
3.2 编号与分组
| 编号段 | 用途 | Folder |
|---|---|---|
| TC-0xx | 前置准备(登录/连接设备/获取资源) | F0-Setup |
| TC-1xx | 正常流程 | F1-xxx |
| TC-2xx | 高级/组合场景 | F2-xxx |
| TC-3xx | 回读验证(创建后查询确认) | F3-xxx |
| TC-4xx | 校验异常/业务异常 | F4-xxx |
| TC-5xx | 清理 | F5-清理 |
F0-Setup 首个请求依认证方式而定:Cookie/Session 为登录请求(TC-001 登录 + TC-002 业务前置);Bearer/Basic/API Key 认证由 Collection auth 配置承载、无登录请求,TC-001 即业务前置请求。
3.3 顺序依赖设计
创建→回读→删除形成闭环:创建类用例提取资源 ID 存入 Collection 变量,回读用例使用该 ID,清理用例循环删除所有已创建资源。
输出:用例计划表
向用户输出用例计划表并等待确认:
| 用例编号 | 名称 | 端点 | 输入要点 | 预期 |
|---------|------|------|---------|------|
| TC-001 | 登录 | POST /login | 合法凭证 | 200 + 用户名 |
| ... | ... | ... | ... | ... |
计划表上方须显式标注:覆盖模式(「正常场景模式」/「全路径模式」,用户可在确认点要求切换);若步骤 3.0 命中历史场景,还须标注文件处理策略:「复用已有文件 <Collection 路径>,原地更新」或「新建文件 <Collection 路径>」。
确认循环(修改后必须再次确认): 初次输出计划表后等待用户确认;若用户提出修改意见,按意见修改后重新输出更新后的用例计划表并再次等待用户确认。用户未明确确认前,禁止进入步骤 4(生成 Collection);修改 → 确认可循环多轮,直到用户明确确认。
步骤4:生成 Collection
代码模式库见 collection-patterns.md,完整示例见 collection-example.json。
4.1 Collection(v2.1 JSON)
info.schema固定为https://schema.getpostman.com/json/collection/v2.1.0/collection.json- 按 Folder 分组(F0-F5),每个请求的
name以用例编号开头(如TC-101 xxx) - Collection 级 auth 配置依认证方式填充(见步骤1.2 对应的 auth 参考文件)
variable字段同时承载静态变量(baseUrl、业务前置参数,预填值)和动态变量(资源 ID 等,初始值为空字符串,由脚本pm.collectionVariables.set()填充)- 每个请求的
event中编写 test 脚本(断言),需要动态数据时加 prerequest 脚本
4.2 七个必备代码模式
① 登录请求(Cookie/Session) ② 动态传参 ③ 空闲资源选择 ④ 时间戳去重 ⑤ 资源 ID 收集 ⑥ 业务异常三层断言 ⑦ 清理循环。
各模式的详细说明与完整 JSON/JS 示例见 collection-patterns.md 第 3-10 节;其中登录请求配置以 auth-cookie-session.md 为唯一权威版本。
4.3 JSON 合法性校验
生成后用 node -e "JSON.parse(require('fs').readFileSync('<file>','utf8'))" 校验每个 JSON 文件。
步骤5:Newman 执行 + 报告
详细指南见 newman-execution-guide.md。
5.1 主集合
newman run <Collection>.postman_collection.json \
-x \
-r cli,htmlextra \
--reporter-htmlextra-export ./reports/<name>-report.html \
--reporter-htmlextra-title "<模块名> API 测试报告" \
--timeout-request 30000 \
--delay-request 500
5.2 HARD STOP(硬性终止——不可跳过)
> Newman 运行完毕即工作流终止点。无论退出码为 0(全部通过)还是非 0(存在失败),唯一允许的下一步是:记录 CLI 统计数据 → 进入步骤 6 输出结果 → 停止。
失败用例是合法的、预期的测试结果(测试的价值正是暴露问题),不是需要 agent 修复的“错误”。
以下行为绝对禁止(无例外、无需判断“是否合理”):
| # | 禁止行为 |
|---|---|
| 1 | 修改已生成的 Collection JSON 文件(包括 URL、Header、Body、变量) |
| 2 | 修改、删除、放宽任何 test 脚本中的断言 |
| 3 | 修改 prerequest 脚本逻辑 |
| 4 | 以任何理由重新运行 newman run(包括“验证修复”“重试”“排除偶发失败”) |
| 5 | 分析失败原因后尝试“修正”测试数据或预期值 |
| 6 | 向用户提议“我来修复”或主动给出修复 diff(仅可陈述失败事实) |
唯一允许的输出动作: 从 CLI 输出中提取统计数据(总请求数、总断言数、通过数、失败数、失败用例名称列表),连同报告文件路径,交给步骤 6 呈现。
如果用户在此之后明确要求修复,那是新一轮用户指令,不属于本工作流的自动行为。
步骤6:输出结果(工作流终点)
6.1 更新 record.md 台账
Newman 执行完毕后,将本次执行写回 <输出目录>/record.md(首次执行则创建):环境信息有变化时覆盖「测试环境」;场景记录原地更新(同一场景只保留一条最新记录),含用例计划表和步骤 5 实际执行的完整 newman 命令;执行历史追加一行摘要。
台账模板:
# API 测试记录台账
## 测试环境
| 项 | 值 |
|----|----|
| baseUrl | <baseUrl> |
| 认证方式 | Cookie/Session | Bearer | Basic | API Key |
| 用户名 | <username>(Cookie/Session、Basic 时填写) |
| 密码 | <password>(Cookie/Session、Basic 时填写) |
| Token | <token值>(Bearer 时填写) |
| API Key | <key名称>: <value值>(API Key 时填写) |
| 技术栈 | <Spring Boot/Express/...> |
| 输出目录 | <目录> |
## 测试场景记录
### <场景名>(如 order-api)
| 项 | 值 |
|----|----|
| 测试文件 | <Collection 路径> |
| 报告文件 | <报告 HTML 路径> |
| 覆盖端点 | GET/POST ... |
| 用例范围 | TC-001 ~ TC-5xx,共 N 条 |
| 最近执行 | <日期时间>,通过 X / 失败 Y |
#### 手动执行命令(步骤 5 实际执行的命令原文,可直接复制复测)
```bash
newman run <实际Collection路径> \
-x \
-r cli,htmlextra \
--reporter-htmlextra-export <实际报告路径> \
--reporter-htmlextra-title "<模块名> API 测试报告" \
--timeout-request 30000 \
--delay-request 500
```
#### 用例计划表(步骤 3 确认后版本)
| 用例编号 | 名称 | 端点 | 输入要点 | 预期 |
|---------|------|------|---------|------|
| TC-001 | ... | ... | ... | ... |
| ... | ... | ... | ... | ... |
## 执行历史
| 时间 | 场景 | 结果 | 备注 |
|------|------|------|------|
| ... | ... | 通过/失败数 | 新建/更新 |
6.2 输出清单
- 列出生成的文件清单(主集合、报告 HTML、record.md)
- 汇报:用例数、断言数、通过/失败数、失败用例名称列表、报告路径
- 若存在失败用例,仅列出失败用例编号 + 断言名 + 实际值/期望值(原样转述 CLI 输出),不做原因分析、不给修复建议、不询问“是否需要我修复”
> 输出完毕后工作流彻底终止(HARD STOP,见步骤 5.2)。后续修复仅由用户在新指令中指示。
定制化使用指南
触发时可通过自然语言传递以下偏好,未指定则用默认值:
| 偏好项 | 示例说法 | 默认行为 |
|---|---|---|
| 认证方式 | "用 token 认证"/"basic 认证" | 从源码与提示词推断,无法判断时询问 |
| 输出目录 | "输出到 ./qa-tests" | ./api-tests |
| 覆盖范围 | "做全路径测试"/"只测删除接口"/"只要异常用例" | 仅正常场景用例(F0/F1/F3/F5);提示词含"全路径/全覆盖"时四维度全覆盖 |
| 请求节奏 | "请求间隔调大到 2s" | --delay-request 500、--timeout-request 30000 |
常见问题 FAQ
Q1:为什么业务异常要断言 HTTP 200 而不是 4xx/5xx?
很多项目用统一包装返回,业务异常 HTTP 恒为 200(错误在 body 的 code/message);需先确认实际响应格式再写断言。响应格式确认方法见 source-analysis-guide.md 第 5 节。
Q2:需要单独准备 Postman 环境文件(environment)吗?
不需要。所有变量(含凭证占位)内置在 Collection 的 variable 字段,单文件即可运行。
Q3:重复执行会不会产生重复数据?
不会。名称类字段自动拼接时间戳 {{ts}} 去重,且 F5 清理用例会循环删除本次创建的全部资源。
Q4:用例计划表确认后还能改吗?
可以。确认后若需变更,在生成 Collection 前提出即可。
Q5:更多边缘场景(分页接口、文件上传、国际化消息等)怎么办?
见 references/faq-deep.md(深度 FAQ)与 references/anti-patterns.md(常见错误做法对比)。
Q6:用例计划表用户提出修改意见后,可以直接开始生成 Collection 吗?
不可以。修改完成后必须重新输出更新后的用例计划表并再次等待用户确认(见步骤 3「输出:用例计划表」的确认循环规则),用户明确确认后才允许进入步骤 4;修改 → 确认可循环多轮。
安全与数据隐私
- 内置文档凭证不落纸面:技能内置的示例、模式、模板一律使用
<username>/<password>/<实际token值>占位;但生成产物(Collection 变量、record.md 台账)允许写入真实凭证,由用户自行填入与管理。 - 仅本地处理:凭证与测试数据只写入本地 Collection JSON 与 record.md,不上传任何外部服务;建议将含真实凭证的 Collection 与 record.md 加入
.gitignore,或使用变量占位后提交。 - 最小权限原则:仅测试用户明确拥有权限的测试/开发环境服务;不对生产环境、他人服务发起测试请求。
- 清理副作用:创建类资源必须配套 F5 清理用例,避免在被测环境残留测试数据。
参考文件
| 文件 | 内容 |
|---|---|
| references/source-analysis-guide.md | 源码分析方法论(各层提取目标 + 摘要模板) |
| references/testcase-design-spec.md | 用例设计规范(编号/分组/覆盖/数据构造) |
| references/collection-patterns.md | Collection 代码模式库(7 个必备模式 + JSON/JS 示例) |
| references/newman-execution-guide.md | Newman 执行 + 报告 + 常见问题 |
| references/anti-patterns.md | 常见错误用法(反模式)+ 改进对比 |
| references/faq-deep.md | 深度 FAQ(边缘场景/兼容性/排障) |
| references/collection-example.json | 完整示例(虚构 OrderController,Cookie/Session) |
| references/auth-cookie-session.md | Cookie/Session 认证配置 |
| references/auth-bearer-token.md | Bearer Token 认证配置 |
| references/auth-http-basic.md | HTTP Basic 认证配置 |
| references/auth-api-key.md | API Key 认证配置 |
约束
- 生成的 Collection / 示例中不写死项目特定值(具体端口、真实账号密码、真实资源 ID),一律用
{{baseUrl}}、<username>等占位,由 Collection 变量注入。 - 【HARD STOP 规则】 见步骤 5.2。修复后需重新走 4.3 → 5 → 6。
- 每个用例(TC-xxx)只包含一个 HTTP 请求。若场景需要先查询数据提取参数,必须拆分为两个独立用例(前置查询 + 业务操作),通过 Collection 变量传递参数。