商城接口自动化:Mitmproxy代理录制实战指南
商城接口自动化:Mitmproxy代理录制实战指南
一、环境准备与配置
1. 安装与启动
# 安装mitmproxy(Python 3.6+) pip install mitmproxy # 启动录制代理(端口8080) mitmdump -w mall_recording.mitm -p 8080 # 查看可用接口 mitmproxy --help
2. 客户端代理配置
手机 | WiFi设置手动代理,服务器=电脑IP,端口=8080,安装CA证书 |
浏览器 | 安装Proxy SwitchyOmega插件,配置HTTP/HTTPS代理=127.0.0.1:8080 |
命令行 | 使用
|
二、基础流量录制
1. 简单录制模式
# 录制所有流量到文件 mitmdump -w mall_recording.mitm -p 8080 # 播放录制的流量 mitmdump -n -r mall_recording.mitm -p 8081
2. 过滤指定域名
# 只录制商城相关域名 mitmdump -w mall_recording.mitm -p 8080 --filter "~d mall.com ~d api.mall.com"
三、自动化录制脚本
1. 智能录制脚本
# smart_recorder.py
from mitmproxy import http
import json
class Recorder:
def __init__(self):
self.api_count = 0
self.flows = []
def request(self, flow: http.HTTPFlow):
if "api.mall.com" in flow.request.host:
flow.metadata["start_time"] = time.time()
self.api_count += 1
print(f"捕获API请求: {flow.request.method} {flow.request.path}")
def response(self, flow: http.HTTPFlow):
if "api.mall.com" in flow.request.host:
latency = time.time() - flow.metadata["start_time"]
status = flow.response.status_code
print(f"API响应: {status} 延迟: {latency:.2f}s")
self.flows.append({
"url": flow.request.url,
"method": flow.request.method,
"request": flow.request.text,
"response": flow.response.text,
"status": status,
"latency": latency
})
addons = [Recorder()]
2. 启动带脚本的录制
mitmdump -s smart_recorder.py -w mall_recording.mitm -p 8080
四、流量分析与转换
1. 生成自动化测试用例
# generate_testcases.py
import json
from mitmproxy import io
from mitmproxy.exceptions import FlowReadException
def convert_to_pytest(flow):
template = f"""
def test_{flow.request.path.replace('/', '_')}():
url = "{flow.request.url}"
headers = {dict(flow.request.headers)}
data = {flow.request.text if flow.request.text else None}
response = requests.{flow.request.method.lower()}(
url,
headers=headers,
json=data if flow.request.method in ["POST", "PUT"] else None
)
assert response.status_code == {flow.response.status_code}
assert response.json() == {flow.response.text}
"""
return template
with open("mall_recording.mitm", "rb") as f:
flows = []
reader = io.FlowReader(f)
try:
for flow in reader.stream():
if "api.mall.com" in flow.request.host:
flows.append(flow)
except FlowReadException as e:
print(f"流量文件损坏: {e}")
with open("test_api_auto.py", "w") as f:
f.write("import requests\n\n")
for flow in flows[:10]: # 取前10个生成用例
f.write(convert_to_pytest(flow))
五、高级录制技巧
1. 接口自动分类
# api_classifier.py
API_CATEGORIES = {
"user": ["/login", "/register", "/profile"],
"product": ["/products", "/search", "/detail"],
"order": ["/cart", "/checkout", "/payment"]
}
def request(self, flow: http.HTTPFlow):
for category, paths in API_CATEGORIES.items():
if any(p in flow.request.path for p in paths):
flow.metadata["category"] = category
break
else:
flow.metadata["category"] = "other"
2. 敏感数据脱敏
# data_scrubber.py
def response(self, flow: http.HTTPFlow):
if "user" in flow.metadata.get("category", ""):
import json
data = json.loads(flow.response.text)
if "phone" in data:
data["phone"] = "***" + data["phone"][-4:]
if "address" in data:
data["address"] = "<REDACTED>"
flow.response.text = json.dumps(data)
六、自动化测试集成
1. 结合Pytest框架
# conftest.py
import pytest
from mitmproxy.tools.main import mitmdump
import threading
@pytest.fixture(scope="session")
def proxy():
def run():
mitmdump(["-s", "recorder.py", "-w", "test_flows.mitm"])
t = threading.Thread(target=run, daemon=True)
t.start()
yield
# 测试结束后停止代理
@pytest.fixture
def recorded_flows():
from mitmproxy import io
flows = []
with open("test_flows.mitm", "rb") as f:
reader = io.FlowReader(f)
try:
for flow in reader.stream():
flows.append(flow)
except:
pass
return flows
2. 流量断言测试
# test_replay.py
def test_order_flow(recorded_flows):
order_flows = [f for f in recorded_flows if "/order/" in f.request.path]
for flow in order_flows:
response = requests.request(
flow.request.method,
flow.request.url,
headers=dict(flow.request.headers),
data=flow.request.content
)
assert response.status_code == flow.response.status_code
if flow.response.headers.get("Content-Type") == "application/json":
assert response.json() == flow.response.json()
七、CI/CD集成方案
1. GitHub Actions配置
name: API Test with Mitmproxy
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install mitmproxy pytest requests
- name: Run tests
run: |
mitmdump -s recorder.py -w test_flows.mitm &
pytest tests/ -v
- name: Upload artifacts
uses: actions/upload-artifact@v2
with:
name: test-flows
path: test_flows.mitm
八、最佳实践建议
- 录制策略:按业务场景分开录制(登录流程、下单流程等)每个场景录制3-5次获取典型用例
- 数据管理:
- 自动化增强:Response:"""
- 异常检测:
九、典型问题解决方案
1. HTTPS证书问题
# 启动时跳过证书验证 mitmdump --ssl-insecure -w flows.mitm # 手动信任证书(手机端) adb push ~/.mitmproxy/mitmproxy-ca-cert.cer /sdcard/ # 然后在设置中安装证书
2. 录制文件过大
# 按大小自动分割文件
from mitmproxy import ctx
class Rotator:
def __init__(self):
self.count = 0
self.max_size = 100 * 1024 * 1024 # 100MB
def running(self):
if os.path.getsize(ctx.options.flow_detail) > self.max_size:
self.count += 1
new_file = f"recording_{self.count}.mitm"
os.rename(ctx.options.flow_detail, new_file)
3. 移动端请求捕获不全
# 强制拦截所有流量
def request(flow):
if flow.request.host not in ["api.mall.com", "static.mall.com"]:
print(f"拦截非商城流量: {flow.request.host}")
flow.kill()
通过这套实战方案,您可以快速实现:
- 商城接口的自动化录制
- 流量到测试用例的自动转换
- 异常接口的智能检测
- 与CI系统的无缝集成
- 可追溯的接口文档生成
建议从核心交易链路开始实施,逐步扩大覆盖范围,最终建立完整的接口自动化测试体系。
进阶高级测试工程师 文章被收录于专栏
《高级软件测试工程师》专栏旨在为测试领域的从业者提供深入的知识和实践指导,帮助大家从基础的测试技能迈向高级测试专家的行列。 在本专栏中,主要涵盖的内容: 1. 如何设计和实施高效的测试策略; 2. 掌握自动化测试、性能测试和安全测试的核心技术; 3. 深入理解测试驱动开发(TDD)和行为驱动开发(BDD)的实践方法; 4. 测试团队的管理和协作能力。 ——For.Heart
查看3道真题和解析