【day5】调用AI接口,生成自动化测试用例

发布于:2025-04-16 ⋅ 阅读:(13) ⋅ 点赞:(0)

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/"
    )

备注:目前生成的用例并不能直接调用使用,需要再手动调整脚本


网站公告

今日签到

点亮在社区的每一天
去签到