Python + requests + pytest + allure + Jenkins 构建完整的接口自动化测试框架

今天我们来讲解一个非常实用且在企业中广泛应用的技能组合:使用 Python + requests + pytest + allure + Jenkins 构建完整的接口自动化测试框架,实现测试执行、断言验证和精美报告生成,并集成到持续交付流程中。

课程核心目标:

掌握一套从编写测试用例、执行测试、验证结果(断言)、生成可视化报告到集成到自动化流程(CI/CD)的完整接口自动化测试解决方案。

教学目标分解:

  1. 知识目标:

    • 理解接口自动化测试的核心概念、价值和适用场景。
    • 掌握 requests 库的核心方法 (get, post, put, delete 等) 用于发送 HTTP 请求。
    • 理解 pytest 测试框架的优势、基本结构 (test_ 前缀、assert)、Fixture 机制和参数化。
    • 掌握 pytest 中常用的断言方法(特别是针对响应状态码、响应体 JSON/文本、响应头)。
    • 了解 allure-pytest 的作用,理解如何通过装饰器 (@allure.title, @allure.description, @allure.step) 和动态方法 (allure.attach) 增强测试报告。
    • 理解 Jenkins 在持续集成/持续交付 (CI/CD) 中的角色,以及如何配置 Jenkins Job 来自动执行测试并收集报告。
  2. 技能目标:

    • 环境搭建: 能独立安装和配置 Python 环境,并使用 pip 安装 requests, pytest, pytest-html, allure-pytest 等必要库。
    • 请求构建: 能熟练使用 requests 构造包含 URL、Headers、Params、Body (JSON/Form Data) 的 HTTP 请求。
    • 响应处理: 能正确解析和处理 HTTP 响应对象,获取状态码、响应头、响应体 (JSON/文本)。
    • 断言编写: 能针对接口响应的不同方面(状态码、特定字段值、数据结构、响应时间阈值等)编写精确、有效的 pytest 断言。
    • 测试组织: 能使用 pytest 组织测试用例(模块、类),合理使用 Fixture 管理测试前置/后置操作(如登录获取 Token、清理测试数据)。
    • 参数化: 能使用 @pytest.mark.parametrize 实现测试用例的参数化,提高用例复用率。
    • 报告增强: 能使用 allure 装饰器为测试用例和步骤添加描述、标题、严重级别,并能附加请求/响应数据、截图(如有 UI 关联)等丰富报告内容。
    • 报告生成: 能通过命令行生成 Allure 报告并查看。
    • Jenkins 集成: 能在 Jenkins 上创建 Job,配置源码管理(如 Git),添加构建步骤执行 pytest 命令并生成 Allure 结果,配置构建后操作发布 Allure 报告。
  3. 素质目标:

    • 培养严谨的测试思维和对软件质量的追求。
    • 提升自动化脚本编写的规范性和可维护性意识。
    • 理解持续集成在快速反馈和质量保障中的重要性。
    • 增强问题排查和调试能力(分析失败用例的请求/响应)。

具体示例:测试一个用户登录接口

假设我们有一个用户登录接口:POST /api/login

  • 请求体 (JSON): {"username": "test_user", "password": "secret"}
  • 成功响应 (JSON): {"code": 200, "message": "success", "data": {"token": "eyJhbGciOiJ..."}}
  • 失败响应 (JSON - 密码错误): {"code": 401, "message": "Invalid password", "data": null}

1. 创建测试文件 (test_login.py)

python 复制代码
import pytest
import requests
import allure
import json

# 定义基础 API URL (通常放在配置文件或 Fixture 中)
BASE_URL = "http://your-api-server.com"

# 使用 Fixture 获取测试数据 (这里简化,实际可能从文件读取)
@pytest.fixture(scope="module")
def login_data():
    return [
        ("test_user", "secret", 200, "success", True),  # 成功用例
        ("test_user", "wrong_pass", 401, "Invalid password", False),  # 密码错误
        ("non_exist_user", "any_pass", 404, "User not found", False),  # 用户不存在
    ]

# 测试类
@allure.feature("用户认证模块")
class TestLoginAPI:

    @allure.story("用户登录接口")
    @allure.title("测试用户登录 - {username}")  # 使用参数动态设置标题
    @allure.severity(allure.severity_level.CRITICAL)  # 设置用例严重级别
    @pytest.mark.parametrize("username, password, exp_code, exp_message, is_success", login_data())
    def test_user_login(self, username, password, exp_code, exp_message, is_success):
        """
        测试用户登录接口的各种场景
        """
        # 1. 构造请求 URL 和请求体
        url = f"{BASE_URL}/api/login"
        payload = json.dumps({
            "username": username,
            "password": password
        })
        headers = {
            'Content-Type': 'application/json'
        }

        # 2. 发送 POST 请求 (使用 allure 记录步骤和请求详情)
        with allure.step("发送登录请求"):
            allure.attach(payload, name="Request Body", attachment_type=allure.attachment_type.JSON)
            response = requests.post(url, headers=headers, data=payload)

        # 3. 记录响应详情到 Allure 报告
        with allure.step("验证响应"):
            # 附加响应状态码和响应体
            allure.attach(f"Status Code: {response.status_code}", name="Response Status")
            try:
                resp_json = response.json()
                allure.attach(json.dumps(resp_json, indent=2), name="Response Body", attachment_type=allure.attachment_type.JSON)
            except json.JSONDecodeError:
                allure.attach(response.text, name="Response Body (Text)")

        # 4. 断言 - 核心验证点
        # 4.1 断言状态码
        assert response.status_code == exp_code, f"期望状态码 {exp_code}, 实际为 {response.status_code}"

        # 4.2 解析响应 JSON (如果预期是 JSON)
        try:
            resp_data = response.json()
        except json.JSONDecodeError:
            pytest.fail(f"响应不是有效的 JSON: {response.text}")

        # 4.3 断言响应中的 code 字段
        assert resp_data.get("code") == exp_code, f"期望 code 字段为 {exp_code}, 实际为 {resp_data.get('code')}"

        # 4.4 断言响应中的 message 字段
        assert resp_data.get("message") == exp_message, f"期望 message 字段为 '{exp_message}', 实际为 '{resp_data.get('message')}'"

        # 4.5 根据是否成功登录断言 token 存在与否 (可选)
        if is_success:
            assert "token" in resp_data.get("data", {}), "登录成功时 data 中应包含 token 字段"
            assert isinstance(resp_data["data"]["token"], str) and len(resp_data["data"]["token"]) > 0, "token 应为非空字符串"
        else:
            assert resp_data.get("data") is None, "登录失败时 data 字段应为 null"

        # 4.6 (可选) 断言响应时间在可接受范围内
        assert response.elapsed.total_seconds() < 2, f"登录请求耗时过长: {response.elapsed.total_seconds()}秒"

2. 执行测试并生成 Allure 结果

在项目根目录下运行命令:

bash 复制代码
pytest test_login.py --alluredir=./allure_results
  • pytest test_login.py: 执行指定的测试文件。
  • --alluredir=./allure_results: 告诉 pytest 将 Allure 需要的原始结果数据(JSON, TXT 等)输出到 allure_results 目录。

3. 生成并查看 Allure 报告

bash 复制代码
allure serve ./allure_results

这条命令会启动一个本地 Web 服务器,并在你的默认浏览器中打开生成的 Allure 报告。报告将包含:

  • 清晰的测试套件、测试类、测试用例结构。
  • 每个用例的标题、描述、严重级别。
  • 详细的步骤记录("发送登录请求"、"验证响应")。
  • 在步骤中附加的请求体 (JSON) 和响应体 (JSON/Text)。
  • 断言结果(通过/失败)。
  • 统计信息(总用例数、通过率、失败率、跳过率)。
  • 图表展示(持续时间、通过率趋势等)。

4. Jenkins 集成 (简要步骤)

  1. 安装必要插件: 在 Jenkins 中安装 Allure PluginPipeline (或 Freestyle project 所需插件)。
  2. 创建 Job:
    • 源码管理: 配置 Git/SVN 拉取你的测试代码仓库。

    • 构建步骤:

      • Shell Command / Windows Batch Command:
      bash 复制代码
      pip install -r requirements.txt  # 安装依赖
      pytest /path/to/tests --alluredir=./allure_results  # 执行测试,生成结果
    • 构建后操作:

      • Allure Report: 配置 Results pathallure_results (与 --alluredir 指定的路径一致)。
  3. 保存并构建: 保存 Job 配置,手动或通过代码提交触发构建。
  4. 查看报告: 构建成功后,在 Jenkins Job 页面会出现 Allure Report 链接,点击即可查看生成的 Allure 报告。

总结

通过这个示例,我们实践了使用 Python requests 发送请求、pytest 组织用例和进行断言、allure 生成丰富详尽的测试报告,并了解了如何将其集成到 Jenkins 实现自动化执行。这套组合拳是当前接口自动化测试领域非常主流和高效的解决方案。希望大家能掌握其核心概念和基本操作,并在实际项目中不断练习和深化,提升测试效率和质量保障能力!后续我们可以探讨更高级的主题,如 Fixture 的深入使用、测试数据驱动、Mock 服务、分布式执行等。

相关推荐
咕白m6252 小时前
通过 Python 在 PDF 中添加页面
python
wa的一声哭了3 小时前
Linux服务器配置ssh免密登陆多台服务器、服务器别名配置
linux·运维·服务器·网络·arm开发·python·ssh
勇往直前plus3 小时前
ElasticSearch详解(篇二)
大数据·elasticsearch·jenkins
咖啡の猫3 小时前
Python中的输出函数
开发语言·数据库·python
小坏讲微服务3 小时前
Spring Cloud Alibaba 2025.0.0 整合 ELK 实现日志
运维·后端·elk·spring cloud·jenkins
朱一头zcy4 小时前
下载安装pycharm 并通过pycahrm来驱动Anaconda来运行Python程序
ide·python·pycharm
CodeLongBear4 小时前
Python数据分析 -- Pandas基础入门学习笔记:从核心概念到实操代码
python·conda·pandas
B站_计算机毕业设计之家4 小时前
python手写数字识别计分系统+CNN模型+YOLOv5模型 深度学习 计算机毕业设计(建议收藏)✅
python·深度学习·yolo·计算机视觉·数据分析·cnn
咖啡の猫5 小时前
二进制与字符编码
python
Tech_Lin5 小时前
手搓工具之手写签字识别提取工具
python