1、项目结构建议
project/
├── api_docs/ # 存放接口文档
│ └── XX系统.swagger.json
├── ai_generator/ # AI测试用例生成模块
│ └── test_case_generator.py
├── tests/ # 生成的测试用例
│ └── test_user_api.py
├── conftest.py # pytest配置
├── url/ # 存放url
│ └── xx模块url.py
└── requirements.txt
XX系统.swagger.json来源
2、新增空的xx模块url.py
3、编写自动化封装api的脚本,自动化生成测试用例
这里需要安装第三方库zhipuai
可以借鉴:https://blog.csdn.net/weixin_41665637/article/details/147113443?
from zhipuai import ZhipuAI
import json
import re
import logging
from pathlib import Path
from typing import Dict, List
class TestCaseGenerator:
def __init__(self, api_key: str):
self.client = ZhipuAI(api_key=api_key)
self.logger = logging.getLogger(__name__)
# pytest测试用例模板
self.test_template = """import pytest
import requests
import logging
import certifi
from faker import Faker
from {url_module} import URLManager
from test_data.auth_params import valid_credentials, invalid_credentials
# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# 全局配置
fake = Faker('zh_CN')
class TestBase:
\"\"\"测试基类\"\"\"
@pytest.fixture(scope="session")
def url_manager(self):
\"\"\"URL管理器\"\"\"
return URLManager(base_url="{base_url}")
@pytest.fixture(scope="session")
def auth_token(self, url_manager):
\"\"\"获取认证令牌\"\"\"
try:
response = requests.post(
url_manager.login,
json=valid_credentials,
verify=certifi.where(),
timeout=10
)
response.raise_for_status()
return response.json().get("token")
except Exception as e:
logger.error(f"登录失败: {{e}}")
pytest.fail("认证失败")
@pytest.fixture
def headers(self, auth_token):
\"\"\"请求头\"\"\"
return {{
"Authorization": f"Bearer {{auth_token}}",
"Content-Type": "application/json"
}}
@pytest.fixture
def test_data(self):
\"\"\"生成测试数据\"\"\"
return {{
"id": fake.random_int(min=1000, max=9999),
"name": fake.word(),
"description": fake.sentence()
}}
class TestAPIs(TestBase):
\"\"\"自动生成的API测试用例\"\"\"
{test_cases}
"""
def generate_test_cases(self, swagger_data: Dict, output_path: str, base_url: str):
"""
生成完整的测试用例文件
:param swagger_data: Swagger文档数据
:param output_path: 测试文件输出路径
:param base_url: API基础地址
"""
try:
# 生成测试用例内容
test_cases = self._generate_test_methods(swagger_data)
# 填充模板(修复括号问题)
final_code = self.test_template.format( # <-- 这里添加完整括号
url_module="api.urlservice1",
base_url=base_url,
test_cases="\n".join(test_cases)
) # <-- 添加闭合括号
# 保存文件
self._save_to_file(output_path, final_code)
self.logger.info(f"测试用例已生成:{output_path}")
except Exception as e:
self.logger.error(f"生成测试用例失败:{str(e)}")
raise
def _generate_test_methods(self, swagger_data: Dict) -> List[str]:
"""生成所有测试方法"""
test_methods = []
for path, methods in swagger_data["paths"].items():
for method, details in methods.items():
# 生成单个测试方法
test_case = self._create_test_case(
path=path,
method=method.upper(),
summary=details.get("summary", ""),
parameters=details.get("parameters", [])
)
test_methods.append(test_case)
return test_methods
def _create_test_case(self, path: str, method: str, summary: str, parameters: List) -> str:
"""创建单个测试用例模板"""
# 处理方法名
method_name = self._generate_method_name(path, method)
# 处理路径参数
path_params = self._parse_path_params(path)
url_expression = self._generate_url_expression(path)
# 生成请求模板
request_template = self._generate_request_template(method, parameters)
return f'''
@pytest.mark.{method.lower()}
def {method_name}(self, url_manager, headers, test_data):
\"\"\"{summary}\"\"\"
try:
# 构造请求
url = {url_expression}
response = requests.{method.lower()}(
url,
headers=headers,
{request_template}
timeout=10
)
# 验证响应
self._validate_response(response)
except requests.exceptions.RequestException as e:
logger.error(f"请求失败:{{str(e)}}")
pytest.fail(f"接口请求异常:{{str(e)}}")
except json.JSONDecodeError:
logger.error("响应数据解析失败")
pytest.fail("响应数据格式错误")
'''
def _generate_method_name(self, path: str, method: str) -> str:
"""生成测试方法名"""
clean_path = re.sub(r"[{}]", "", path)
return f"test_{method.lower()}_{clean_path.strip('/').replace('/', '_')}"
def _parse_path_params(self, path: str) -> List[str]:
"""解析路径参数"""
return re.findall(r"{(\w+)}", path)
def _generate_url_expression(self, path: str) -> str:
"""生成URL表达式"""
return f'f"{path}".format(**test_data)'
def _generate_request_template(self, method: str, parameters: List) -> str:
"""生成请求模板"""
if method.upper() in ["POST", "PUT", "PATCH"]:
return "json=test_data,"
return ""
def _validate_response(self, response) -> str:
"""生成响应验证代码"""
return """
# 基础断言
assert 200 <= response.status_code < 300, f"无效状态码:{response.status_code}"
# 验证数据结构
response_data = response.json()
assert isinstance(response_data, (dict, list)), "响应数据结构无效"
# 动态验证字段
if isinstance(response_data, dict):
assert "id" in response_data, "响应缺少ID字段"
"""
def _save_to_file(self, path: str, content: str):
"""保存到文件"""
output_path = Path(path)
output_path.parent.mkdir(parents=True, exist_ok=True)
with open(output_path, "w", encoding="utf-8") as f:
f.write(content)
# 使用示例
if __name__ == "__main__":
# 初始化生成器
test_gen = TestCaseGenerator(api_key="your_api_key")
# 读取Swagger文件
swagger_path = "D:/python_test/pythonProject/project/api_docs/123..swagger.json"
with open(swagger_path, encoding="utf-8") as f:
swagger_data = json.load(f)
# 生成测试用例
test_gen.generate_test_cases(
swagger_data=swagger_data,
output_path="D:/python_test/pythonProject/project/tests/test_apis.py",
base_url="https://staging.bu.xa.com/api/"
)
备注:目前生成的用例并不能直接调用使用,需要再手动调整脚本