pytest-参数化
前言
像unittest框架中可以通过ddt进行参数化操作,那么pytest也可以进行参数化操作,通过parametrize修饰器就可以将数据参数化传入测试用例
parametrize参数化
1、parametrize修饰器使用
修饰器:@pytest.mark.parametrize('usr,pwd',
[('usr1','1111'),
('usr2','2222')])
示例代码:
import pytest class Test_01(): @pytest.mark.parametrize('usr,pwd', [('usr1','1111'), ('usr2','2222') ]) def test_01(self,usr,pwd): print(f'用户名:{usr},密码:{pwd}')
输出结果:
pytest.mark.parametrize定义了2个参数usr和pwd,同时也定义了2组数据,那么输出打印也会是2组测试用例打印
2、测试数据添加标签
从上图输出结果看,test_01的每组数据打印后面跟着都是两个传入参数值以"-"分隔,例如[usr1-1111],但有时候想换个通俗易懂的标签呢?那么pytest也提供了对应的参数来给每条测试数据进行标签
方法一:通过pytest.param中的id进行添加标签
import pytest class Test_01(): # 方法一:通过pytest.param中的id进行添加标签 @pytest.mark.parametrize('usr', [pytest.param('小明',id=('usr1')), pytest.param('张三',id=('usr2')), pytest.param('王五',id=('usr3')) ] ) def test_01(self,usr,): print(f'用户名:{usr}')
输出结果:
可以看红框标注的标签名称已经跟每组测试数据输入的id参数一致了
注:如果想要输入中文标签,请将本地安装python目录Lib\site-packages\_pytest\compat.py下的ascii_escaped方法中的encode和decode的编码格式改成utf-8,标签即可输出中文
方法二:设置ids参数(如需要输入中文,可在测试的根目录的pytest.ini配置文件中加上disable_test_id_escaping_and_forfeit_all_rights_to_community_support = True)
pytest.ini代码如下:
[pytest] addopts = -p no:warnings disable_test_id_escaping_and_forfeit_all_rights_to_community_support = True
ids参数示例代码:
import pytest class Test_01(): @pytest.mark.parametrize('usr', ['张三', '李四', '王五'],ids=['张三账号','李四账号','王五账号'] ) def test_01(self,usr): print(f'用户名:{usr}')
输出结果:
输出打印中,能够正常输出ids设定的标签名
3、跳过指定测试数据
如果测试过程,某条测试用例需要跳过,那么可以通过:pytest.param('aa','bb',marks=pytest.mark.skip)进行跳过
import pytest class Test_01(): @pytest.mark.parametrize('usr',[ '李四','王五', pytest.param('张三',marks=pytest.mark.skip) ]) def test_01(self,usr,): print(f'用户名:{usr}')
输出结果:
张三的测试数据已经显示被SKIPPED(跳过)
4、多组参数组合执行
在测试过程中,通常会遇到2个变量参数要分别组合,变成测试数据输入进行测试,比如2个parametrize都存放3组数据,那么组合出来的数据就有3*3=9个测试数据输入
import pytest class Test_01(): @pytest.mark.parametrize('usr',[ '张三', '李四', '王五' ]) @pytest.mark.parametrize('age',[ '22','12','32' ]) def test_01(self,usr,age): print(f'用户名:{usr},年龄:{age}')
输出结果:
5、字典格式参数化
以上都是通过列表中传入元组的形式进行参数化,但也可以通过字典格式进行参数化
import pytest class Test_01(): @pytest.mark.parametrize('list',[ {'user':'张三','pwd':'1111'}, {'user':'李四','pwd':'2222'} ]) def test_01(self,list): print(f'用户信息:{list},用户名:{list["user"]}.密码:{list["pwd"]}')
输出结果:
传入的参数是字典格式,取对应的值,通过字典的key就可以
6、params参数化
除了parametrize来做参数化,fixture中也提供了方法来支持参数化,params参数就可以做到,request参数是用来接收fixture传入的参数,request.parma依次接收传入的数据
import pytest data = ['张三','李四',['小明','小红']] @pytest.fixture(params=data) def login(request): print('用户名显示') print(request.param)print('执行结束') class Test_01: def test_01(self,login): print('用例一执行')
输出结果:
pytest也可以像parametrize的ids一样对每个传入测试数据的用例进行备注区分,参数也是ids,当pytest的ids为默认时,那么备注就会是函数名0、1、2……依次增加
注:如果已经使用ids进行标签,那么ids标签数量要与测试数据个数一致,要不然会提示报错
import pytest data = ['张三','李四',['小明','小红']] @pytest.fixture(params=data,ids=['t1','t2','t3']) def login(request): print('用户名显示') print(request.param) yield request.param print('执行结束') class Test_01: def test_01(self,login): print('用例一执行')
输出结果:
fixtrue也可以传入多个参数,当多个参数以字典形式传入后,request.param也会依次返回字典格式的数据,yield可以将其返回给测试用例,通过key进行拿取对应数值
import pytest data = [{'user':'admin','pwd':'admin'}, {'user':'root','pwd':'123456'} ] @pytest.fixture(params=data,ids=['t1','t2']) def login(request): print('用户名显示') print(request.param) yield request.param print('执行结束') class Test_01: def test_01(self,login): print(f'登陆用户名:{login["user"]},密码:{login["pwd"]}')
输出结果: