Python + pytest + requests + Allure 接口自动化测试框架搭建流程
一、先定目标
先别急着写代码,先把范围定清楚:
1. 测什么:冒烟、回归、核心链路、契约校验
2. 给谁用:测试、开发、CI
3. 跑在哪:本地、测试环境、预发、生产只读校验
4. 要什么输出:测试报告、失败日志、告警通知
二、技术选型
常见建议:
- 语言:Python
- 测试框架:pytest
- HTTP请求:requests
- 报告:allure
- 配置管理:yaml / json
- 日志:logging
- CI:Jenkins / GitLab CI / GitHub Actions
三、框架目录设计
先把骨架搭起来,别一开始就把用例堆在一起。
api-test-framework/
├── common/ # 公共方法
│ ├── request.py # 二次封装HTTP请求
│ ├── logger.py
│ ├── assert_util.py
│ └── db_util.py
├── config/ # 环境配置
│ ├── test.yaml
│ ├── pre.yaml
│ └── prod.yaml
├── data/ # 测试数据
├── testcases/ # 测试用例
│ ├── user/
│ └── order/
├── fixtures/ # pytest夹具
├── reports/ # 测试报告
├── conftest.py
├── pytest.ini
├── requirements.txt
└── run.py
四、核心模块搭建顺序
建议按这个顺序做,不容易返工:
1. 配置模块
- 支持多环境切换
- 管理 base_url、账号、数据库、token 等
2. 日志模块
- 请求地址、入参、响应、断言结果都要落日志
- 失败时能快速定位
3. HTTP请求封装
- 统一 GET/POST/PUT/DELETE
- 自动带公共 header、token
- 统一超时、重试、异常处理
4. 断言模块
- 状态码断言
- 响应字段断言
- 业务码断言
- 数据库断言
5. 数据管理
- 测试数据和代码分离
- 支持参数化
- 支持关联提取,如登录 token、订单号
6. Fixture机制
- 登录前置
- 环境初始化
- 清理测试数据
7. 报告模块
- 生成 Allure 报告
- 展示请求、响应、失败原因
五、用例设计规范
框架搭好了,用例规范决定后面能不能维护。
建议每条用例包含:
- 用例标题
- 接口名称
- 请求方法
- 请求地址
- 请求头
- 请求参数
- 预期结果
- 是否依赖前置接口
- 是否需要数据库校验
用例分层建议:
- smoke:核心接口能不能通
- regression:主要业务回归
- negative:异常场景、边界值、权限校验
六、关键能力补齐
真正可用的框架,通常还要补这些:
- token自动获取与刷新
- 接口依赖处理
- 响应结果提取
- 数据库校验
- mock或桩服务
- 失败重跑
- 标签管理:@smoke、@regression
- 并发执行:pytest-xdist
七、接入CI/CD
本地能跑不算完成,接入流水线才算成型。
基本流程:
1. 拉代码
2. 安装依赖
3. 执行 pytest
4. 生成 Allure 报告
5. 发送钉钉/企业微信/邮件通知
八、落地实施建议
不要一次做很重,分三步最稳:
1. V1
- 请求封装
- 配置管理
- 日志
- 基础断言
- 报告输出
2. V2
- 参数化
- 关联提取
- 数据库校验
- 多环境切换
3. V3
- CI集成
- 通知告警
- 并发执行
- 失败重试
- 质量统计
九、常见坑
这几个问题最常见:
- 用例和数据强耦合,后期难维护
- 公共请求封装过度,反而不好扩展
- 日志不完整,失败后查不出原因
- 环境配置混乱,测试数据互相污染
- 接口依赖过重,导致用例不稳定
十、推荐结论
如果你是从 0 开始搭,建议直接用这套:
- Python + pytest + requests + allure + yaml
这是当前最省成本、最容易招人接手、也最容易接 CI 的组合。
我可以下一步直接给你一份可运行的接口自动化测试框架目录模板,包括:
- 项目结构
- 核心代码
- 示例接口用例
- Allure 报告配置
- Jenkins 执行命令
如果要写一个根据Swagger 生成接口自动化测试脚本的skill 应该怎么做
• 我先看一下 skill-creator 的说明,按它的约束给你一个可落地的设计方案。
• Ran Get-Content -Path 'C:\Users\70269\.codex\skills\.system\skill-creator\SKILL.md' -TotalCount 260
└ ---
name: skill-creator
... +257 lines (ctrl + t to view transcript)
Conclude this step when there is a clear sense of the functionality the skill should support.
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
• 可以,这类 skill 最实用的做法不是把"Swagger 转测试脚本"的逻辑全写进 SKILL.md,而是:
1. SKILL.md 负责定义触发条件、工作流程、边界
2. scripts/ 里放真正的解析和生成脚本
3. assets/templates/ 里放测试模板
4. references/ 里放 OpenAPI 字段映射规则
这样可维护,也符合 skill 的设计方式。
建议目标
先把 skill 收敛成一个明确能力:
- 输入:Swagger/OpenAPI json 或 yaml,本地文件或 URL
- 输出:pytest + requests 风格的接口自动化测试脚本
- 范围:优先生成"可跑的冒烟脚本",不是一步到位生成完整业务回归
这是关键。Swagger 能告诉你接口结构,但通常给不了完整业务断言、鉴权上下文、前置依赖和脏数据治理。第一版先生成"骨架 + 基础断言 + 参数样例"最稳。
推荐目录
swagger-testgen/
├── SKILL.md
├── agents/
│ └── openai.yaml
├── scripts/
│ ├── generate_from_openapi.py
│ ├── normalize_spec.py
│ └── sample_data.py
├── references/
│ ├── openapi-mapping.md
│ └── generation-rules.md
└── assets/
└── templates/
└── pytest-requests/
├── test_api.py.j2
├── conftest.py.j2
├── client.py.j2
└── pytest.ini.j2
SKILL.md 怎么写
SKILL.md 不要长篇解释原理,只写 Codex 真正执行时需要遵循的规则。
一个实用版本大概这样:
---
name: swagger-testgen
description: Generate API automation test scripts from Swagger/OpenAPI specs. Use when the user wants to create pytest/requests interface tests from a Swagger or OpenAPI json/yaml file or URL, including
smoke tests, request models, fixtures, and basic assertions.
---
# Swagger Test Generator
## When to use
Use this skill when the user wants to:
- generate API test scripts from Swagger/OpenAPI
- scaffold pytest interface automation from API docs
- convert OpenAPI specs into runnable test cases
## Inputs to collect
Need one of:
- local OpenAPI/Swagger file
- OpenAPI URL
- existing repo target directory
Also determine:
- target framework: default `pytest + requests`
- auth style: bearer token / cookie / none
- output scope: smoke only / smoke + negative skeleton
## Workflow
1. Locate the OpenAPI source.
2. Run `scripts/normalize_spec.py` to normalize Swagger 2.0 / OpenAPI 3.x into one internal structure.
3. Read `references/openapi-mapping.md` for field mapping rules only if needed.
4. Run `scripts/generate_from_openapi.py` to generate:
- api client
- fixtures
- test files grouped by tag
- sample payloads
5. Prefer examples/defaults/enums from the spec when generating request data.
6. Add only stable assertions by default:
- status code
- response content type
- required top-level fields if explicitly defined
7. For missing business expectations, emit TODO comments instead of inventing assertions.
## Generation rules
- Group tests by tag first, then by path.
- Generate one happy-path smoke case per operation by default.
- Generate negative cases only for clearly derivable constraints:
- missing required field
- invalid enum
- unauthorized access when security is declared
- Do not guess irreversible business logic.
- Reuse existing repo structure if present.
## Validation
After generation:
- ensure imports resolve
- ensure output paths exist
- if a local test environment is configured, run a narrow smoke selection
真正关键的是生成脚本
skill 的核心价值其实在 scripts/generate_from_openapi.py,不是 SKILL.md。
这个脚本至少要做 5 件事:
1. 识别 Swagger/OpenAPI 版本
- swagger: "2.0"
- openapi: 3.0.x / 3.1.x
2. 统一结构
把这些字段归一化:
- 路径 paths
- 方法 get/post/...
- 参数 parameters
- 请求体 requestBody
- 响应 responses
- 鉴权 security
- Schema / $ref
3. 生成样例数据
优先级建议:
- example
- examples
- default
- enum[0]
- 按类型兜底生成:string/int/bool/array/object
4. 映射成测试用例
每个 operation 生成:
- test_<tag>_<operationId>_smoke
- 必要 fixture
- 基础断言
5. 按模板渲染
用 jinja2 最合适,别手拼字符串。
生成规则建议
这是成败关键。建议你把规则写死在 skill 里,而不是每次临场发挥。
最小可用规则:
- 每个接口生成 1 条正向用例
- 必填参数缺失时生成 1 条反向骨架
- 有鉴权声明时生成 1 条未授权骨架
- 断言只做确定性的:
- HTTP 状态码
- JSON 可解析
- 响应结构里 schema 明确声明的必填字段
不要默认生成这些高风险内容:
- 业务成功文案断言
- 精确数据库结果断言
- 强依赖前置状态的链路用例
- 需要环境账户准备的数据
这些只能生成 TODO。
一个合理的输出长什么样
例如输出到项目里:
tests/api/
├── conftest.py
├── client.py
├── test_user.py
├── test_order.py
└── data/
├── user_payloads.json
└── order_payloads.json
test_user.py 里每个接口一条 smoke case,像这样:
def test_create_user_smoke(api_client, auth_headers):
payload = build_create_user_payload()
resp = api_client.post("/users", json=payload, headers=auth_headers)
assert resp.status_code in (200, 201)
body = resp.json()
assert isinstance(body, dict)
这类脚本是"可执行骨架",不是"业务完备用例",定位要讲清楚。
references 应该放什么
建议两个参考文件就够了:
references/openapi-mapping.md
- Swagger 2.0 和 OpenAPI 3.x 的字段映射
- definitions/components.schemas
- body parameter/requestBody
- securityDefinitions/securitySchemes
references/generation-rules.md
- 样例数据生成规则
- 文件命名规则
- case 命名规则
- 允许生成哪些断言,禁止猜哪些断言
assets/templates 里放什么
模板建议固定 4 个:
- client.py.j2:请求封装
- conftest.py.j2:fixture、鉴权、base_url
- test_api.py.j2:测试文件模板
- pytest.ini.j2:pytest 配置
这样生成逻辑和代码样式分离,后续切 pytest + httpx 或 playwright api 也容易。
MVP 实施顺序
别一开始做太全。按这个顺序最稳:
1. 支持本地 openapi.json/yaml
2. 支持 Swagger 2.0 和 OpenAPI 3.x 归一化
3. 生成 pytest + requests smoke 脚本
4. 支持 bearer token fixture
5. 支持按 tag 分文件
6. 再补负向 case 和 URL 输入
容易踩的坑
最常见的是这几个:
- 把 Swagger 当成完整测试依据,结果断言全是猜的
- 直接字符串拼 Python 代码,后面很难维护
- $ref 没解开,生成出来全是残缺结构
- 一个 skill 里硬编码太多项目私有逻辑,复用性很差
- 生成"所有接口全量回归",最后全是无效脚本
结论
这个 skill 最合理的定位是:
"根据 Swagger/OpenAPI 生成接口自动化测试骨架和冒烟脚本,并把不确定的业务断言显式留成 TODO。"
这样它真的可用,也不会伪智能。
下一步可以直接落一版 swagger-testgen 骨架:SKILL.md、generate_from_openapi.py、模板文件和一个可运行的 pytest 示例。
常见的 Python + pytest + requests + Allure 方案