使用pytest自动化API测试时出现‘got empty parameter set’错误的问题排查求助
问题分析与解决方案
你遇到的这个跳过错误,核心原因是pytest的参数化(@pytest.mark.parametrize)是在测试收集阶段就执行的——这时候你的desafios列表还是空的,因为test_001_post_desafio要等到测试执行阶段才会运行,根本还没来得及填充数据。所以当pytest解析第二个测试的parametrize时,拿到的是空参数集,直接触发了跳过。
怎么解决?
我们需要把数据生成的逻辑提前到测试收集阶段之前,或者用pytest的fixture机制来控制执行顺序,确保数据在第二个测试用例运行前就准备好。这里推荐用session级别的fixture来生成并存储需要的数据,再结合动态参数化来传递给第二个测试。
修改后的代码示例
import pytest import requests import json subdominios = ["20", "21", "22", "23", "24", "25", "99", "22", "11"] # 用session级fixture来预先生成所有需要的验证数据 @pytest.fixture(scope="session") def desafios_data(payload, header): desafios = [] for subdominio in subdominios: response_create = requests.post( "some url" + subdominio, data=json.dumps(payload), headers=header, verify=False ) response_json = response_create.json() desafios.append((response_json["otp"], response_json["idOtp"], subdominio)) # 确保创建接口调用成功 assert response_create.status_code == 200 return desafios # 用pytest钩子函数动态生成第二个测试的参数 def pytest_generate_tests(metafunc): # 只给需要desafio_data参数的测试生成参数 if "desafio_data" in metafunc.fixturenames: # 获取fixture中预先生成的数据 desafios = metafunc.config.getfixturevalue("desafios_data") # 给每个参数组添加id,方便测试报告里区分 ids = [f"subdominio_{sub}" for _, _, sub in desafios] metafunc.parametrize("desafio_data", desafios, ids=ids) # 验证接口的测试用例 def test_002_post_validate(desafio_data, header): otp, idOtp, subdominio = desafio_data response = requests.post( "some Url 1" + idOtp + "some url2" + subdominio, data=json.dumps({"otp": otp}), headers=header, verify=False ) assert response.status_code == 204
为什么这样可行?
desafios_data是session级别的fixture,会在所有测试用例执行之前运行一次,提前生成并存储好所有需要的otp、idOtp和subdominio数据。pytest_generate_tests钩子函数会在测试收集阶段被调用,它可以动态地从fixture中获取数据,为第二个测试生成参数化的用例——这时候数据已经存在了,不会出现空参数集的问题。- 每个验证请求都会作为独立的测试用例运行,和你原来的设计一致,优雅地拆分了创建和验证的逻辑。
其他可选方案
如果你不想用钩子函数,也可以直接在第二个测试用例里遍历desafios_data的数据,不过这样所有验证会被当作一个测试用例执行(只要有一个失败就全失败),不如参数化的方式直观。示例:
def test_002_post_validate(desafios_data, header): for otp, idOtp, subdominio in desafios_data: response = requests.post( "some Url 1" + idOtp + "some url2" + subdominio, data=json.dumps({"otp": otp}), headers=header, verify=False ) assert response.status_code == 204, f"验证subdominio {subdominio}失败"
内容的提问来源于stack exchange,提问作者Fedex
相关产品推荐
相关产品推荐

