要实现根据Flask接口文档自动生成测试脚本、自动执行多次并汇总结果 ,可以通过解析Swagger文档 +动态生成pytest测试用例 +测试结果汇总的流程完成。以下是完整的Python实现方案:

一、环境准备
-
安装依赖库:
bashpip install requests pytest pytest-html flasgger
requests
:发送HTTP请求;pytest
:测试框架,支持自动发现和执行测试;pytest-html
:生成HTML测试报告;flasgger
:Flask的Swagger文档生成库(确保你的Flask应用已集成,用于提供结构化的Swagger JSON)。
二、核心逻辑实现
1. 获取并解析Swagger文档
Flask应用通常通过/swagger.json
提供结构化的Swagger文档(需集成flasgger
)。我们需要先获取该文档,解析出所有接口的信息(路径、方法、参数、预期响应)。
python
import requests
from typing import Dict, List, Any
def get_swagger_doc(swagger_url: str) -> Dict[str, Any]:
"""获取Swagger JSON文档"""
response = requests.get(swagger_url)
response.raise_for_status() # 确保请求成功
return response.json()
def parse_swagger_interfaces(swagger_doc: Dict[str, Any]) -> List[Dict[str, Any]]:
"""解析Swagger文档,提取接口信息(路径、方法、参数、响应)"""
interfaces = []
paths = swagger_doc.get("paths", {})
for path, methods in paths.items():
for method, details in methods.items():
# 仅处理GET/POST/PUT/DELETE方法
if method.lower() in ["get", "post", "put", "delete"]:
interface = {
"path": path,
"method": method.upper(),
"parameters": details.get("parameters", []), # 接口参数(查询/请求体)
"responses": details.get("responses", {}) # 预期响应
}
interfaces.append(interface)
return interfaces
2. 生成测试用例
根据解析出的接口信息,生成覆盖正常流、异常流、边界条件的测试用例。例如,登录接口的测试用例包括:正常登录、错误用户名、错误密码、缺少参数等。
python
def generate_test_cases(interfaces: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
"""根据接口信息生成测试用例"""
test_cases = []
for interface in interfaces:
path = interface["path"]
method = interface["method"]
# 1. 登录接口(/login,POST)
if path == "/login" and method == "POST":
test_cases.extend([
{
"name": "login_success", # 测试用例名称
"request": {"json": {"username": "admin", "password": "password123"}},
"expected": {"status_code": 200, "json": {"access_token": str, "message": "登录成功"}}
},
{
"name": "login_wrong_username",
"request": {"json": {"username": "nonexistent", "password": "password123"}},
"expected": {"status_code": 401, "json": {"message": "用户名或密码错误"}}
},
{
"name": "login_missing_username",
"request": {"json": {"password": "password123"}},
"expected": {"status_code": 400, "json": {"message": "缺少必填字段: username"}}
}
])
# 2. 客户列表接口(/crm/customers,GET)
elif path == "/crm/customers" and method == "GET":
test_cases.extend([
{
"name": "get_customers_success",
"request": {},
"expected": {"status_code": 200, "json": {"customers": list, "pagination": dict}}
},
{
"name": "get_customers_unauthorized",
"request": {},
"expected": {"status_code": 401, "json": {"message": "缺少访问令牌"}}
}
])
# 3. 创建客户接口(/crm/customers,POST)
elif path == "/crm/customers" and method == "POST":
test_cases.extend([
{
"name": "create_customer_success",
"request": {"json": {"name": "李四", "email": "lisi@example.com", "phone": "13900139000"}},
"expected": {"status_code": 201, "json": {"id": int, "name": "李四", "email": "lisi@example.com", "message": "客户创建成功"}}
},
{
"name": "create_customer_missing_name",
"request": {"json": {"email": "lisi@example.com", "phone": "13900139000"}},
"expected": {"status_code": 400, "json": {"message": "缺少必填字段: name"}}
}
])
return test_cases
3. 动态生成pytest测试函数
利用pytest的动态测试生成能力,为每个测试用例生成独立的测试函数,自动发送请求并验证响应。
python
def generate_test_function(test_case: Dict[str, Any]) -> callable:
"""为单个测试用例生成pytest测试函数"""
def test_func():
# 构造请求URL和方法
method = test_case["request"].get("method", "POST").upper()
path = test_case["path"]
url = f"http://localhost:8000{path}" # 替换为你的API地址
request_data = test_case["request"]
# 发送HTTP请求
if method == "POST":
response = requests.post(url, json=request_data.get("json", {}))
elif method == "GET":
response = requests.get(url, params=request_data.get("params", {}))
elif method == "PUT":
response = requests.put(url, json=request_data.get("json", {}))
elif method == "DELETE":
response = requests.delete(url, params=request_data.get("params", {}))
else:
raise ValueError(f"不支持的请求方法: {method}")
# 验证1:状态码是否符合预期
expected_status = test_case["expected"]["status_code"]
assert response.status_code == expected_status, \
f"测试用例[{test_case['name']}]失败:预期状态码{expected_status},实际{response.status_code}"
# 验证2:响应体结构和类型是否符合预期
expected_json = test_case["expected"]["json"]
response_json = response.json()
for key, expected_type in expected_json.items():
assert key in response_json, \
f"测试用例[{test_case['name']}]失败:响应缺少字段[{key}]"
assert isinstance(response_json[key], expected_type), \
f"测试用例[{test_case['name']}]失败:字段[{key}]类型错误(预期{expected_type.__name__},实际{type(response_json[key]).__name__})"
return test_func
4. 主程序:注册测试用例并执行
将上述步骤整合,自动生成测试用例、注册测试函数,并通过pytest执行测试,生成HTML报告。
python
if __name__ == "__main__":
# 1. 配置Swagger文档地址(根据你的Flask应用调整)
SWAGGER_URL = "http://localhost:8000/swagger.json"
try:
# 2. 获取并解析Swagger文档
swagger_doc = get_swagger_doc(SWAGGER_URL)
interfaces = parse_swagger_interfaces(swagger_doc)
print(f"✅ 成功解析到 {len(interfaces)} 个接口")
# 3. 生成测试用例
test_cases = generate_test_cases(interfaces)
print(f"✅ 生成 {len(test_cases)} 个测试用例")
# 4. 动态注册测试函数到pytest
for test_case in test_cases:
test_name = f"test_{test_case['name']}" # pytest测试函数命名规则
test_func = generate_test_function(test_case)
globals()[test_name] = test_func # 将测试函数加入全局命名空间
# 5. 执行测试(生成HTML报告)
print("
🚀 开始运行测试...")
pytest.main([
__file__, # 当前脚本
"-v", # 详细模式(显示每个测试用例的结果)
"--html=report.html", # 生成HTML报告
"--self-contained-html" # 报告包含所有依赖(无需额外文件)
])
except Exception as e:
print(f"❌ 执行失败:{e}")
exit(1)
三、使用说明
-
启动Flask应用 :确保你的Flask应用运行在
http://localhost:8000
,并集成了flasgger
(可通过/swagger.json
访问Swagger文档)。 -
运行测试脚本 :执行上述Python脚本:
bashpython test_crm_api.py
-
查看结果 :
- 命令行会输出详细的测试结果(通过/失败/错误);
- 生成
report.html
文件,打开后可查看测试用例详情 、失败原因 和汇总统计(通过率、失败数等)。
四、扩展功能
1. 自动执行多次测试
通过pytest的--count
参数指定执行次数(例如执行5次):
bash
pytest.main([
__file__,
"-v",
"--html=report.html",
"--count=5" # 执行5次测试
])
2. 更灵活的测试数据管理
若测试数据需要复用或参数化,可以使用pytest的@pytest.mark.parametrize
装饰器。例如,登录接口的多组用户名/密码:
python
import pytest
@pytest.mark.parametrize("username, password, expected_message", [
("admin", "password123", "登录成功"),
("nonexistent", "password123", "用户名或密码错误"),
("admin", "wrongpassword", "用户名或密码错误")
])
def test_login_parametrized(username, password, expected_message):
# 发送请求并验证
response = requests.post("http://localhost:8000/login", json={"username": username, "password": password})
assert response.status_code == 200 if "成功" in expected_message else 401
assert expected_message in response.json()["message"]
3. 集成CI/CD
可以将测试脚本集成到CI/CD pipeline(如GitHub Actions、Jenkins),每次代码提交后自动执行测试并生成报告。
总结
该方案通过解析Swagger文档 实现测试用例的自动生成,通过pytest动态测试 实现自动执行,通过HTML报告实现结果汇总。完全符合"根据接口文档生成测试脚本、自动执行多次、汇总结果"的需求,且支持灵活扩展(如参数化测试、CI/CD集成)。