API 测试(api-testing)
SkillDev toolsAPI testing from OpenAPI/Swagger or case schemas: parameters, boundaries, auth, idempotency, concurrency, error responses, data consistency; runnable scripts; k6 handoff. Not for: Web UI flows, manual case writing. 接口级测试:参数/边界/鉴权/幂等/并发/错误响应/数据一致性,产出脚本与结果;含 k6 压测。不用于:Web UI、手动用例。
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the API 测试(api-testing) skill
What this skill tells your AI
The instructions your AI receives, as published by fishzjp/qa-skills in skills/api-testing/SKILL.md and read by ahel’s review.
接口级测试——E2E 之外的另一条执行路径。
- 输入:API 文档(OpenAPI/Swagger)、用例 Schema 中
execution_model可自动化的接口用例、被测环境信息(base URL、账号/Token);性能轴(类型矩阵轴 1)移交包专项移交_性能_*.yaml - 输出(落盘):API 测试脚本(pytest + requests,或项目既定技术栈)+ 执行分报告
测试报告_api_{日期}.md(命名按../core/report-template.md头注,条目按其 §3 对齐;qa 断点判据按此文件名核收);性能承接时另产 k6 压测脚本与压测报告(references/k6-conventions.md) - 边界:Web UI 流程 →
automated-e2e-testing;接口手动用例设计 →test-case-writing
When to Use
- 给定 OpenAPI/Swagger 文档,需要产出并运行接口自动化测试
- 从用例 Schema 中筛出接口级可自动化用例,转换为 API 脚本执行
- 需要覆盖鉴权/越权、幂等、并发写、错误响应等接口层专项
- 给定性能移交包或接口清单,需要生成并运行压测脚本(k6)——按
references/k6-conventions.md
When NOT to Use
- Web UI 交互流程(点击 / 页面状态)→
automated-e2e-testing - 编写接口的手动测试用例 →
test-case-writing - 端到端流水线 →
qa编排 - 独立压测环境搭建与容量保障 → 运维/专项协作(agent 侧压测承接见
references/k6-conventions.md;外部执行场景按test-strategy的移交包) - Mock Server 搭建 → 开发协作事项,不在本 skill 范围
脚手架(默认 pytest + requests,可替换为项目既定栈)
api-tests/
├── conftest.py # fixture:base_url、会话/Token、环境配置(环境变量注入,可由 .env 加载,不硬编码)
├── common/
│ └── client.py # 统一请求封装:日志、超时、鉴权头、断言辅助
├── test_{模块}_{接口}.py # 一个接口一个文件,test 名沿用 TC 编号
└── requirements.txt
# common/client.py —— 统一请求封装(requests.Session 不支持 base_url,必须显式拼接)
import requests
class Client:
def __init__(self, base_url: str, token: str):
self.base_url = base_url.rstrip("/")
self.s = requests.Session()
self.s.headers.update({"Authorization": f"Bearer {token}"})
def request(self, method: str, path: str, **kwargs):
url = f"{self.base_url}/{path.lstrip('/')}"
kwargs.setdefault("timeout", 10)
return self.s.request(method, url, **kwargs)
def get(self, path, **kw): return self.request("GET", path, **kw)
def post(self, path, **kw): return self.request("POST", path, **kw)
# put / delete / patch 同理扩展
def login(user: str, password: str) -> str:
"""按项目实际登录接口实现(如 POST /login 换 token)——占位,勿直接照抄"""
raise NotImplementedError("按项目登录接口实现")
# conftest.py 关键 fixture
import os
import pytest
from common.client import Client, login
@pytest.fixture(scope="session")
def client():
base_url = os.environ["API_BASE_URL"] # 环境与账号不硬编码,走环境变量
token = login(os.environ["API_USER"], os.environ["API_PASSWORD"])
return Client(base_url, token)
敏感信息(账号/Token/环境地址)一律环境变量注入,不进代码仓库(与
automated-e2e-testing的 constants 约定一致)。
工作流
1. 输入解析与范围确认
- 从 OpenAPI 文档提取:接口清单、参数表(必填/类型/范围/默认值)、错误码、鉴权方式
- 从用例 Schema 过滤:
automation.framework: api的用例,以及execution_model: dev-collab且 framework 非 manual 的用例 → 转换对象(test 名沿用 TC 编号:test_TC_05_01_写入字段读回一致;framework: manual 的 dev-collab 用例保持手动协作,不转) - 环境未知 → 向用户索取(base URL、账号、是否可写生产旁路环境),不确定就问,不猜接口行为(提问格式与裁决落盘统一按
../core/clarify-pattern.md,场景用「执行确认」)
2. 用例设计(此时加载 ../core/testing-principles.md,方法细节 ../core/methods/data-driven.md)
每接口一张参数矩阵(分析过程工具,心内构建或草稿即可,不落盘为中间文件——结论直接进用例,与 test-case-writing 的无中间文件口径一致),逐参数 × 逐属性;重点覆盖:
| 类别 | 必测点 |
|---|---|
| 参数 | 必填缺失 / 类型错误 / 边界值(空/最值/超大,见 ../core/methods/boundary.md) |
| 鉴权 | 无 Token / 过期 Token / 错误 Token / 越权(他人资源 id)——越权方法基线 ../core/methods/permission.md(Role×Action×Resource 矩阵 + 垂直/水平两类越权,即类型矩阵轴 2 的执行层) |
| 幂等 | 同一业务键重复提交 → 不重复创建;重试安全 |
| 并发 | 并发写同一资源 → 无互相覆盖、无中间态 |
| 错误响应 | 每个错误码的触发条件 + 响应体结构与文案 |
| 数据一致性 | 写后读回一致;级联操作后关联数据一致 |
多参数接口的组合面按 ../core/methods/data-driven.md 第 2 节显式降档执行(全组合 → 成对组合 → 风险挑选):单参数逐属性做全;跨参数交互(跨字段规则 / 参数依赖)选档覆盖,成对组合为默认档;降档与被排除的组合面写进 rationale,不静默收缩。
3. 脚本编写
- 一个接口一个 test 文件;一条 test 只测一个点,沿用 TC 编号命名
- 输出预算纪律(防空截断):同类边界/参数校验用
@pytest.mark.parametrize合并为一条参数化测试,禁止逐值展开重复的 test 函数或超长重复断言——单文件超过 ~250 行即应参数化收敛(生成通道有输出上限,超限会截断产生不可编译代码) - 断言三件套:状态码 + 业务码 + 响应体关键字段(不写"只断言 200"的弱断言)
- 测试数据自建自清理(setup 创建 / teardown 删除),不依赖执行顺序;数据模板(唯一名等)先核对材料字段约束(maxLength/枚举/格式),模板总长(前缀+随机段)≤ 约束上限 −2——顶格即数据自建缺陷(实测自伤案例:唯一名模板 22 字符撞契约 maxLength 20);参数矩阵逐格回检跨字段业务规则(如"使用门槛不能低于面额")——违反规则的组合改取合法值或拆为显式负向用例,不做隐式非法组合(实测自伤案例:金额顶格 1000 配低于面额的门槛 → 400 THRESHOLD_INVALID 而用例期望 201)
- 依赖前序状态的用例显式在前置里造数,不假设库里有数据(造数模式:
../core/methods/data-factory.md——makeX 构造器 / 造数通道三选一 / 前缀隔离)
4. 运行与结果
报告条目与统计口径以 ../core/report-template.md 为唯一来源(含机读摘要片段,收尾时加载),保证可直接拼装进 qa 收尾的最终报告:
pytest api-tests/ -v --tb=short # 全量
pytest api-tests/test_coupon_create.py # 单文件
- 失败用例先分辨:被测系统 Bug / 环境问题 / 用例自身错误——不自行假设,环境问题与预期歧义列出来问用户(提问格式同上,
../core/clarify-pattern.md) - 失败 ≥3 条时升级为批量分流:先按
../core/triage.md四分类定类(A 真缺陷 / B 资产问题〔B1 产品预期变更・B2 用例自身错误〕/ C 环境与依赖故障 / D 不稳定),仅 A 类进入下方 Bug 记录流程,替换单条逐个分辨 - 流水线运行:以 headless 模式进入 PR 冒烟 / 夜间任务时,检查点降级为未决项、产物按规范落盘、退出码分离基建故障与真缺陷——三条约定见
../core/pipeline-integration.md(此时加载) - 结构覆盖补充证据(可选):有被测服务代码且测试环境可插桩(Python 服务
coverage run启动;JVM 服务 JaCoCo agent)时,接口用例跑完取被测服务的行/分支覆盖率作为补充 E3 证据——只用于发现零覆盖/极低覆盖的接口与分支(漏测信号,转补用例或策略升档),不作为追高的虚荣指标;无插桩条件直接跳过,不阻塞交付 - 发现的 Bug:证据(请求/响应原文、时间戳)按
../core/report-template.md§3 记录条目,根因分析移交bug-analysis
5. 交付
脚本路径 + 运行统计(§2 执行统计:P0/P1/P2 × 通过/失败/阻塞/未执行,按 ../core/report-template.md)+ Bug 条目 + 遗留问题清单 + (有插桩时)结构覆盖摘要:零覆盖/低覆盖接口清单。
契约与 schema 一致性(类型矩阵轴 10 执行层)
轴 10 决策 include 时按本节执行(决策与档位来自 test-strategy 的 type_scope,本节只管执行形态);报告回收走 report-template §7 表,执行方列如实填写。
两层形态(分工不互替)
| 层 | 对象 | 做法 |
|---|---|---|
| schema 一致性 | 响应体 vs OpenAPI 定义逐字段(类型/必填/枚举) | Schemathesis 一条命令接入:schemathesis run openapi.yaml --base-url $API_BASE_URL;或手写 jsonschema 断言并入现有 test 文件 |
| 结构级负向 fuzzing | 结构鲁棒性(类型错位 / 超长 / 格式畸变) | Schemathesis 自动生成非法输入。与 §2 参数矩阵分工:矩阵管业务语义组合,fuzzing 管结构鲁棒性 |
概念边界
- schema 校验 ≠ 消费者契约:schema 只验"响应符合定义",契约验"消费者-提供者允许的交互集合"
- Pact 式消费者驱动契约的启用判据:多消费者微服务且字段演进频繁——单系统项目 schema 一致性即可,不上契约框架
- 契约执行物按 type_scope 进执行策略裁决(脚本型消费方式);mock/沙箱依赖不可得按矩阵 R5 记 blocked
执行纪律
- fuzzing 发现的 5xx / 未定义错误码视为候选缺陷,逐条归因(与 §4 失败分辨同流程),不自动记 Bug
- schema 校验全过 ≠ 契约没问题:字段语义变更(结构未变)schema 层不可见,语义回归靠业务用例
Common Mistakes
| 错误 | 后果 | 正确做法 |
|---|---|---|
| 只断言状态码不断言业务码与响应体 | Bug 漏检(200 但业务失败) | 状态码 + 业务码 + 关键字段三件套 |
| 硬编码环境地址与账号 | 无法跨环境运行、泄露敏感信息 | 环境变量注入 |
| 测试间共享可变状态 | 顺序依赖、偶发失败 | 自建数据 + 自清理,每条独立 |
| 重复提交不测幂等 | 重复创建类 Bug 上线 | 同业务键重复请求必测 |
| 失败一律记为 Bug | 误报污染报告 | 先归因(系统/环境/用例),歧义问用户 |
| 无权限/越权只测前端表现 | 后端未拦截的越权漏检 | 直接调接口测鉴权(无 Token/过期/他人 id) |
| 多参数接口逐值全展开或随手抽样 | 组合爆炸截断 / 参数交互缺陷静默漏测 | 按降档策略显式选档(全组合 → 成对 → 风险挑选),降档留痕 |
| Schema 用例带占位符/虚构入口仍直接翻成脚本 | 幻觉脚本:能跑通但测的不是真实接口 | 转换前过 ../core/executability.md 红线闸门,补不了的暂缓进遗留清单 |
| schema 校验全过就当契约没问题 | 字段语义变更(结构未变)漏检 | schema 只验结构;语义回归靠业务用例(见「契约与 schema 一致性」节) |
Signals
- GitHub stars
- 28
- Forks
- 5
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
api-testing- Source
- github.com/fishzjp/qa-skills