pytest.fixture接收参数的两种方式
request.param
方式一:通过pytest.mark.parametrize参数化传入
实现方式:执行用例时,通过@pytest.mark.parametrize指定fixture并传入参数
单参数传递
对于一般的用例参数化来说,@pytest.mark.parametrize的第一个参数通常是用例函数的形参名称,不同的形参用,分隔,如:“datas, tips”;第二个参数则是需要传入的数据,数据与第一个参数中定义的形参一 一对应,不同形参的数据通过元组或列表分隔,如:[(1,2),(3,4)],则1和2为datas的数据,3和4为tips的数据。
以上是对于将参数传入用例的情况,而对于需要将参数传入fixture的情况来说。使用参数化时,需要指定indirect参数的值为True。
当 indirect=False 时,“setup_func”被当成普通变量;
当 indirect=True 时,“setup_func”被当成函数执行,且 [“a”, “b”]作为函数中的参数传递
如下例:@pytest.mark.parametrize的参数中,第一个参数是需要调用的fixture,第二个参数是传入fixture的数据,第三个参数指定第一个参数作为函数执行;前置函数fixture在函数体内通过request.param接收传入的参数
示例一:单个fixture接收单个参数
@pytest.mark.parametrize('setup_func', ["a", "b"], indirect=True)
def test_func(self, setup_func):
pass
@pytest.fixture(scope="class")
def setup_func(request):
param = request.param
print(param)
return request.param
执行结果:
该例中只传了一个参数,用例执行两次
示例二:多个fixture,各fixture接收单个参数
@pytest.mark.parametrize('setup_func, setup_func2', [(1, 2), (3, 4)], indirect=True)
def test_func(self, setup_func, setup_func2):
print(setup_func, setup_func2)
@pytest.fixture(scope="class")
def setup_func(request):
param = request.param
print(param)
return request.param
@pytest.fixture(scope="class")
def setup_func2(request):
param = request.param
print(param)
return request.param
执行结果:
多参数传递
若fixture需要接收多个参数,此时可以以key:value的形式将不同参数作为数据传入,request.param接收所有数据,fixture取值时根据key去取即可
注意点:字典要包在列表或元组内,不然整个字典会被认为是一个参数,并将k1和k2认为是两组数据,执行两次用例
@pytest.mark.parametrize('setup_func', [{"k1": "v1", "k2": "v2"}], indirect=True)
def test_func(self, setup_func):
print(setup_func)
@pytest.fixture(scope="class")
def setup_func(request):
param = request.param
print(param['k1'], param['k2'])
return request.param
执行结果:
方式二:定义fixture时,通过params传入
params是fixture的其中一个参数,该参数的作用是参数化。通过params传入的参数,在fixture内可以被接收。接收的前提是需要给fixture传一个request参数,则可在fixture内通过request.param接收
params内的数据格式同方法一中相同,这里不再赘述,直接看示例:
@pytest.mark.parametrize('data, expected_tip',
combined_into_tuple(read_xlsx_todict(FILE_PATHS['task_import_form'], 5, sheet_name='test'),
read_xlsx_todict(FILE_PATHS['task_import_form'], 1, 5, sheet_name='test')))
def test_import_task(self, init_import_conf, data, expected_tip):
task = TaskPage(init_import_conf._driver)
print(init_import_conf)
ret_tip = task.fill_import_task_form(init_import_conf, **data)
expected_tip = expected_tip['expected_content']
assert ret_tip == expected_tip
@pytest.fixture(scope="class", params=[{"loc_template_conf": FILE_PATHS['task_import_loc'],
"field_info_conf": FILE_PATHS['task_import_form']}])
def init_import_conf(init_task_center, request):
param = request.param
form = TaskCommonForm(init_task_center._driver)
form.init_form_info(param['loc_template_conf'], param['field_info_conf'])
return form
该例中通过fixture的params参数将数据传给fixture,fixture内通过request.param拿到数据,并将数据作为init_form_info方法的参数传入。test_import_task用例参数传了init_import_conf这个fixture,则用例在执行时会先执行前置函数init_import_conf且可以在用例内拿到该fixture的返回值
总结
如果想要让fixture接收参数,需要在定义fixture时设置参数request,并在fixture内通过request.param拿到参数值