接口抓包联调实战教程(软件测试人员专用)¶
本教程面向软件测试工程师,讲解从抓包分析到接口调试再到自动化落地的完整工作流,把 Fiddler、Postman、Python 三件套串起来。
前置要求¶
| 项目 | 要求 | 获取方式 |
|---|---|---|
| Fiddler 基础 | 会使用 Fiddler 抓取和查看 HTTP/HTTPS 请求 | Fiddler抓包教程-软件测试版 |
| Postman 基础 | 会发送 GET/POST 请求、查看响应 | Postman接口测试教程-软件测试版 |
新手导读¶
这篇教程是把 Fiddler、Postman、Python 串起来的实战流程。基础薄弱时不要三件工具一起学乱,按顺序来:先抓到真实请求,再用 Postman 复现,最后考虑自动化。
你需要完成的最小闭环是:
- 在页面或 App 上操作一次业务。
- 用 Fiddler 找到对应接口。
- 把接口复制到 Postman 并发送成功。
- 根据响应设计测试点。
- 选择稳定接口改写成 Python 自动化。
只要这个闭环跑通,你就真正理解了“抓包联调”的价值。
一、完整工作流概览¶
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 阶段一 │ │ 阶段二 │ │ 阶段三 │
│ 抓包分析 │ ──→ │ 接口调试 │ ──→ │ 自动化落地 │
│ Fiddler │ │ Postman │ │ Python │
└─────────────┘ └─────────────┘ └─────────────┘
↓ ↓ ↓
看到真实请求 验证接口功能 回归测试自动化
理解业务流程 设计测试用例 CI/CD 集成
定位问题 调试参数 持续回归
什么时候用这套流程:
| 场景 | 适用阶段 |
|---|---|
| 新项目接入 | 从抓包开始理解接口 |
| 联调测试 | 抓包看请求 → Postman 验证 |
| Bug 复现 | 抓包抓真实请求 → Postman 重放 |
| 自动化建设 | 抓包导出 → Postman 调试 → Python 落地 |
二、第一阶段:抓包分析¶
2.1 为什么先抓包¶
- 接口文档可能不全或过时
- 抓包能看到 真实的请求/响应
- 了解接口调用顺序和依赖关系
- 发现隐藏接口(前端直接调的、埋点接口)
2.2 Fiddler 抓包步骤¶
Step 1:配置 Fiddler
- 打开 Fiddler →
Tools→Options→HTTPS - 勾选
Decrypt HTTPS traffic - 勾选
Ignore server certificate errors Connections→ 勾选Allow remote computers to connect- 记住端口:默认
8888
Step 2:配置过滤器
只抓目标域名,避免干扰:
Filters → 勾选 Use Filters → Hosts → Show only the following Hosts:
Step 3:操作 App / 网页
正常操作被测系统,Fiddler 自动记录所有请求。
Step 4:分析请求
在会话列表中找到目标接口,查看:
- Inspectors → WebForms:请求参数
- Inspectors → JSON:响应数据
- Inspectors → Headers:请求头(Token、Cookie)
- Statistics:响应时间
2.3 导出请求到 Postman¶
方式 1:复制 cURL(推荐)
Fiddler 右键请求 → Copy → Copy as cURL → Postman 点击 Import → 粘贴 cURL → 自动解析。
方式 2:导出 HAR 文件
Fiddler → File → Export Sessions → Selected Sessions → 选 HTTPArchive (.har) → 在 Postman 中 Import 导入该 HAR 文件。
方式 3:复制原始请求
Fiddler 选中请求 → Inspectors → Raw → 复制全文 → Postman 手动构造。
2.4 分析业务流程¶
抓包后整理接口调用链:
1. POST /api/login → 获取 token
2. GET /api/user/info → 获取用户信息(需 token)
3. GET /api/products → 商品列表(公开)
4. POST /api/cart/add → 加购物车(需 token)
5. POST /api/order/create → 创建订单(需 token)
6. POST /api/order/pay → 支付(需 token + orderId)
记录每个接口的: - 请求方法、URL - 必填参数 - 鉴权方式(Token/Cookie/无) - 依赖关系(哪个接口的输出是下一个的输入)
三、第二阶段:接口调试¶
3.1 在 Postman 中重建请求¶
Step 1:创建 Collection
按业务模块组织:电商系统-用户模块、电商系统-订单模块。
Step 2:配置环境变量
创建 测试环境:
| Variable | Value |
|---|---|
| base_url | https://api-test.example.com |
| username | testuser |
| password | 123456 |
| token | (登录后自动填充) |
Step 3:逐个创建请求
从 Fiddler 导入或手动创建,参数用变量引用:
3.2 链式请求(依赖接口串联)¶
登录接口的 Tests 脚本:
// 登录成功后自动保存 token
pm.test("登录成功", function () {
const json = pm.response.json();
pm.expect(json.code).to.eql(0);
pm.environment.set("token", json.data.token);
});
后续接口的 Header:
3.3 设计测试用例¶
基于抓包分析,为每个接口设计用例:
| 维度 | 测试点 |
|---|---|
| 正常流程 | 正确参数返回预期结果 |
| 必填校验 | 缺少必填字段 |
| 参数类型 | 类型错误(字符串传数字) |
| 边界值 | 长度上下限、数值上下限 |
| 业务规则 | 状态流转、权限校验 |
| 异常场景 | 不存在的 ID、过期数据 |
| 安全 | SQL 注入、XSS、越权 |
3.4 断言脚本¶
// 状态码
pm.response.to.have.status(200);
// 业务 code
const json = pm.response.json();
pm.expect(json.code).to.eql(0);
// 字段存在
pm.expect(json.data.token).to.be.a("string");
// 响应时间
pm.expect(pm.response.responseTime).to.be.below(1000);
// 响应包含
pm.expect(pm.response.text()).to.include("成功");
3.5 Collection Runner 批量执行¶
- 点击 Collection →
Run collection - 选择环境
- 配置迭代次数(数据驱动时 > 1)
- 加载数据文件(CSV/JSON)
- 点击
Run
四、第三阶段:自动化落地¶
4.1 什么时候转自动化¶
| 条件 | 是否转 |
|---|---|
| 接口稳定,频繁回归 | ✅ 转 |
| 接口频繁变动 | ❌ 先不转 |
| 用例执行频率高(每天/每次发布) | ✅ 转 |
| 一次性测试 | ❌ 不转 |
| 团队有 Python 基础 | ✅ 转 |
4.2 从 Postman 到 Python 的映射¶
| Postman | Python |
|---|---|
| Request | requests.get/post() |
| Environment Variables | config.yaml |
| Tests 脚本 | pytest assert |
| Pre-request Script | conftest.py fixture |
| Collection Runner | pytest 命令行 |
| Data File | data/*.yaml |
| Newman | pytest --alluredir |
4.3 项目结构¶
api-automation/
├── config/
│ └── config.yaml # 环境配置
├── apis/ # 接口封装
│ ├── login_api.py
│ └── order_api.py
├── data/ # 测试数据
│ └── login_data.yaml
├── testcases/ # 测试用例
│ ├── test_login.py
│ └── test_order.py
├── common/ # 工具类
│ ├── request_util.py
│ └── yaml_util.py
├── conftest.py
├── pytest.ini
└── requirements.txt
4.4 核心代码¶
config.yaml:
request_util.py:
import requests
class RequestUtil:
def __init__(self):
self.session = requests.Session()
def get(self, url, **kwargs):
return self.session.get(url, timeout=30, **kwargs)
def post(self, url, **kwargs):
return self.session.post(url, timeout=30, **kwargs)
http = RequestUtil()
conftest.py:
import pytest
import yaml
from common.request_util import http
config = yaml.safe_load(open("config/config.yaml", encoding="utf-8"))
env = config[config["env"]]
@pytest.fixture(scope="session")
def base_url():
return env["base_url"]
@pytest.fixture(scope="session")
def login_token(base_url):
resp = http.post(f"{base_url}/api/login", json={
"username": env["username"],
"password": env["password"]
})
return resp.json()["data"]["token"]
test_login.py:
import pytest
from common.request_util import http
class TestLogin:
def test_login_success(self, base_url):
resp = http.post(f"{base_url}/api/login", json={
"username": "testuser",
"password": "123456"
})
assert resp.status_code == 200
assert resp.json()["code"] == 0
assert "token" in resp.json()["data"]
def test_login_wrong_password(self, base_url):
resp = http.post(f"{base_url}/api/login", json={
"username": "testuser",
"password": "wrong"
})
assert resp.json()["code"] == 1001
4.5 执行与报告¶
五、实战案例¶
5.1 案例:电商下单完整链路¶
Step 1:Fiddler 抓包
抓到接口链:
1. POST /api/login → token
2. GET /api/products → 商品列表
3. POST /api/cart/add → 加购物车
4. POST /api/order/create → 创建订单
5. GET /api/order/{id} → 查询订单
Step 2:Postman 调试
- 逐个接口建请求
- 写 Tests 脚本串联(登录存 token → 后续带 token)
- 验证每个接口的正常/异常场景
Step 3:Python 自动化
def test_full_order_flow(base_url, login_token):
headers = {"Authorization": f"Bearer {login_token}"}
# 查询商品
resp = http.get(f"{base_url}/api/products", headers=headers)
product_id = resp.json()["data"]["list"][0]["id"]
# 加购物车
resp = http.post(f"{base_url}/api/cart/add", headers=headers,
json={"productId": product_id, "quantity": 1})
assert resp.json()["code"] == 0
# 创建订单
resp = http.post(f"{base_url}/api/order/create", headers=headers,
json={"addressId": 1})
assert resp.json()["code"] == 0
order_id = resp.json()["data"]["orderId"]
# 查询订单
resp = http.get(f"{base_url}/api/order/{order_id}", headers=headers)
assert resp.json()["data"]["status"] == "WAIT_PAY"
5.2 案例:Bug 复现与定位¶
场景: 用户反馈"下单后订单页看不到订单"。
Step 1:Fiddler 抓包
- 用户操作下单流程
- 抓到
/api/order/create返回 200,code=0 - 但
/api/order/list返回空列表
Step 2:Postman 复现
- 直接调
/api/order/create,拿到 orderId - 调
/api/order/list,确认查不到 - 调
/api/order/{orderId},确认订单存在
Step 3:定位
- 订单创建成功但列表查不到 → 可能是缓存问题或查询条件问题
- 进一步抓包发现 list 接口多了个默认过滤参数
status=PAID - 订单状态是
WAIT_PAY,被过滤了 → Bug 确认
六、常见问题排查¶
6.1 Fiddler 抓不到请求¶
- 检查是否勾选
Capture Traffic - 检查 App 是否走了代理
- 检查是否被过滤器排除
- HTTPS 是否解密开启
6.2 Postman 请求与实际不一致¶
- 检查 Headers 是否完整(特别是 Content-Type)
- 检查 Body 格式(JSON vs form-data)
- 检查环境变量是否生效
6.3 自动化用例偶发失败¶
- 网络抖动:加重试机制
- 数据冲突:用独立测试数据
- 接口变更:及时更新用例
- 依赖服务不稳定:Mock 外部依赖
6.4 Token 过期¶
# conftest.py 中用 session 级 fixture,整轮测试只登录一次
@pytest.fixture(scope="session")
def login_token(base_url):
resp = http.post(f"{base_url}/api/login", json={...})
return resp.json()["data"]["token"]
附录:工具对照速查¶
| 环节 | 工具 | 作用 |
|---|---|---|
| 抓包 | Fiddler / Charles | 看到真实请求 |
| 调试 | Postman / Apifox | 手动验证接口 |
| 自动化 | Python + Pytest | 编码自动化 |
| 报告 | Allure | 生成测试报告 |
| 性能 | JMeter / Locust | 压力测试 |
| Mock | WireMock / Apifox | 模拟接口 |
| CI/CD | Jenkins | 持续集成 |
工作流精髓
抓包理解业务 → Postman 验证功能 → Python 自动化回归。三步走,覆盖从探索到验证到持续回归的完整测试生命周期。