今天我们来讲解一个非常实用且在企业中广泛应用的技能组合:使用 Python + requests + pytest + allure + Jenkins 构建完整的接口自动化测试框架,实现测试执行、断言验证和精美报告生成,并集成到持续交付流程中。
课程核心目标:
掌握一套从编写测试用例、执行测试、验证结果(断言)、生成可视化报告到集成到自动化流程(CI/CD)的完整接口自动化测试解决方案。
教学目标分解:
-
知识目标:
- 理解接口自动化测试的核心概念、价值和适用场景。
- 掌握
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 来自动执行测试并收集报告。
-
技能目标:
- 环境搭建: 能独立安装和配置 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 报告。
- 环境搭建: 能独立安装和配置 Python 环境,并使用
-
素质目标:
- 培养严谨的测试思维和对软件质量的追求。
- 提升自动化脚本编写的规范性和可维护性意识。
- 理解持续集成在快速反馈和质量保障中的重要性。
- 增强问题排查和调试能力(分析失败用例的请求/响应)。
具体示例:测试一个用户登录接口
假设我们有一个用户登录接口: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 集成 (简要步骤)
- 安装必要插件: 在 Jenkins 中安装
Allure Plugin和Pipeline(或Freestyle project所需插件)。 - 创建 Job:
-
源码管理: 配置 Git/SVN 拉取你的测试代码仓库。
-
构建步骤:
- Shell Command / Windows Batch Command:
bashpip install -r requirements.txt # 安装依赖 pytest /path/to/tests --alluredir=./allure_results # 执行测试,生成结果 -
构建后操作:
- Allure Report: 配置
Results path为allure_results(与--alluredir指定的路径一致)。
- Allure Report: 配置
-
- 保存并构建: 保存 Job 配置,手动或通过代码提交触发构建。
- 查看报告: 构建成功后,在 Jenkins Job 页面会出现
Allure Report链接,点击即可查看生成的 Allure 报告。
总结
通过这个示例,我们实践了使用 Python requests 发送请求、pytest 组织用例和进行断言、allure 生成丰富详尽的测试报告,并了解了如何将其集成到 Jenkins 实现自动化执行。这套组合拳是当前接口自动化测试领域非常主流和高效的解决方案。希望大家能掌握其核心概念和基本操作,并在实际项目中不断练习和深化,提升测试效率和质量保障能力!后续我们可以探讨更高级的主题,如 Fixture 的深入使用、测试数据驱动、Mock 服务、分布式执行等。