pytest结合yml文件实现接口自动化测试参数关联的另一种实现方式
·
在接口测试中,使用 pytest 和 yaml 文件结合可以方便地实现参数化测试、接口参数关联以及数据驱动。以下是一个关于接口参数关联和使用 yaml 文件编写用例的详细介绍与示例。
目标
- 接口参数关联:将一个接口的返回值作为另一个接口的入参。
- 使用 YAML 文件:通过 YAML 文件管理测试用例,方便维护和扩展。
- 实现代码简洁、灵活的接口测试框架。
实现步骤
1. 准备工作
-
安装依赖:
pip install pytest pyyaml requests -
示例场景:
- 接口 A:用户登录,返回
token。 - 接口 B:获取用户信息,需要传入
token。
- 接口 A:用户登录,返回
2. YAML 文件编写测试用例
我们使用 YAML 文件来管理接口测试数据。以下是一个示例的 testcases.yml 文件:
# testcases.yml
login:
url: "http://example.com/api/login"
method: "POST"
headers:
Content-Type: "application/json"
data:
username: "test_user"
password: "test_pass"
extract: "token" # 从响应中提取 token
get_user:
url: "http://example.com/api/user"
method: "GET"
headers:
Authorization: "Bearer ${token}" # 使用 token 作为参数
3. 编写测试代码
以下是结合 pytest 和 yaml 文件的测试代码:
import pytest
import yaml
import requests
@pytest.fixture
def load_test_cases():
"""加载 YAML 文件中的测试用例"""
with open("testcases.yml", "r", encoding="utf-8") as file:
test_cases = yaml.safe_load(file)
return test_cases
def extract_value(response, key):
"""从响应中提取指定字段的值"""
try:
return response.json().get(key)
except Exception as e:
raise ValueError(f"无法从响应中提取键 '{key}': {e}")
@pytest.fixture
def login_token(load_test_cases):
"""登录接口,获取 token"""
login_case = load_test_cases["login"]
# 请求登录接口
response = requests.request(
method=login_case["method"],
url=login_case["url"],
headers=login_case["headers"],
json=login_case["data"],
)
# 提取 token
if response.status_code == 200:
token = extract_value(response, login_case["extract"])
if token:
return token
else:
raise ValueError("未能从登录响应中提取 token")
else:
raise AssertionError(f"登录失败,状态码: {response.status_code}, 响应: {response.text}")
def test_get_user_info(load_test_cases, login_token):
"""测试获取用户信息接口"""
user_case = load_test_cases["get_user"]
# 替换参数中的 token
headers = user_case["headers"]
headers["Authorization"] = headers["Authorization"].replace("${token}", login_token)
# 请求用户信息接口
response = requests.request(
method=user_case["method"],
url=user_case["url"],
headers=headers,
)
# 断言
assert response.status_code == 200, f"获取用户信息失败: {response.text}"
assert "user" in response.json(), "响应中未包含用户信息"
4. 代码详解
-
load_test_casesFixture:- 负责加载
testcases.yml文件中的测试用例数据。
- 负责加载
-
login_tokenFixture:- 调用登录接口,提取返回的
token并作为后续接口的参数。
- 调用登录接口,提取返回的
-
extract_value函数:- 用于从接口响应中提取指定的字段值(如
token),支持灵活扩展。
- 用于从接口响应中提取指定的字段值(如
-
接口参数关联:
- 在
testcases.yml文件中,Authorization字段的值使用占位符${token},测试代码会动态替换为实际的token。
- 在
-
测试用例的执行:
test_get_user_info测试用户信息接口时,通过login_token自动获取登录后返回的token。
5. 优化建议
-
分层设计:
- 将请求发送、参数化处理、结果校验分离,便于维护。
-
添加更多断言:
- 校验响应时间、响应字段等,确保接口的可靠性。
-
支持多用例参数化:
- 在 YAML 文件中定义多个用例,使用
pytest.mark.parametrize实现批量测试。
- 在 YAML 文件中定义多个用例,使用
6. 支持多用例参数化
改进后的 testcases.yml:
testcases:
- name: "测试获取用户信息成功"
login:
url: "http://example.com/api/login"
method: "POST"
headers:
Content-Type: "application/json"
data:
username: "test_user"
password: "test_pass"
extract: "token"
get_user:
url: "http://example.com/api/user"
method: "GET"
headers:
Authorization: "Bearer ${token}"
expected_status: 200
expected_key: "user"
- name: "测试无效 token"
login:
url: "http://example.com/api/login"
method: "POST"
headers:
Content-Type: "application/json"
data:
username: "test_user"
password: "wrong_pass"
extract: "token"
get_user:
url: "http://example.com/api/user"
method: "GET"
headers:
Authorization: "Bearer invalid_token"
expected_status: 401
expected_key: null
对应的测试代码:
@pytest.mark.parametrize("case", load_test_cases()["testcases"])
def test_api(case):
"""测试接口"""
# 登录接口
response = requests.request(
method=case["login"]["method"],
url=case["login"]["url"],
headers=case["login"]["headers"],
json=case["login"]["data"],
)
# 提取 token
token = extract_value(response, case["login"]["extract"]) if response.status_code == 200 else None
# 替换 token
headers = case["get_user"]["headers"]
headers["Authorization"] = headers["Authorization"].replace("${token}", token or "invalid_token")
# 请求用户信息接口
response = requests.request(
method=case["get_user"]["method"],
url=case["get_user"]["url"],
headers=headers,
)
# 断言
assert response.status_code == case["expected_status"], f"状态码不匹配: {response.text}"
if case["expected_key"]:
assert case["expected_key"] in response.json(), f"响应中未找到键: {case['expected_key']}"
总结
- 使用
pytest和yaml文件可以实现高效的参数化接口测试。 - 接口参数关联通过提取关键字段(如
token)实现。 - YAML 文件的使用让用例数据和测试逻辑分离,便于维护和扩展。
更多推荐


所有评论(0)