参数化设计方法就是将模型中的定量信息变量化,使之成为任意调整的参数。对于变量化参数赋予不同数值,将可得到不同大小和形状的零件模型。
参数化测试函数使用
- 单参数
- 多参数
- 用例重命名
- 笛卡尔积
使用parametrize()实现参数化
(1)单参数
import pytest
search_list = ['appium','selenium','pytest']
@pytest.mark.parametrize('name',search_list)
def test_search(name):
assert name in search_list
import pytest
@pytest.mark.parametrize('a', [-1, 1, 0, 2, 3])
def test_a(a):
assert 1 == a
(2)多参数
import pytest
import sys
'''
创建测试用例,传入三组参数,每组两个元素,判断每组参数里面表达式和值是否相等。
'''
@pytest.mark.parametrize("test_input,expected",[("3+5",8),("2+5",7),("5*7",30)])
def test_eval(test_input,expected):
assert eval(test_input) == expected
@pytest.mark.parametrize('a,b,expect', [
[1, 1, 2], [0.1, 0.1, 0.2], [1, 0, 1], [-1, 1, 0]
], ids=['int1', 'float', 'zero', 'minus'])
def test_add(a, b, expect):
assert expect == a + b
@pytest.mark.parametrize(['a', 'b', 'expect'], [
[1, 1, 2], [0.1, 0.1, 0.2], [1, 0, 1], [-1, 1, 0]
], ids=['int1', 'float', 'zero', 'minus'])
def test_add(a, b, expect):
assert expect == a + b
(3)用例重命名
对测试用例进行重命名,使用ids对测试用例进行重命名,@pytest.mark.parametrize自带ids这个参数。
不对用例进行重命名:
对用例进行重命名:
import pytest
# 1、参数化的名字,要与方法中的参数名,一一对应,
# 2、如果传递多个参数的话,要放在列表中,列表中嵌套列表 /元组
# 3、ids 的个数 == 传递的数据个数
@pytest.mark.parametrize("test_input,expected",[
("3+5",8),("2+5",7),("7+5",12)
],ids=["number1","number2","number3"])
def test_mark_more(test_input,expected):
assert eval(test_input) == expected
![在这里插入图片描述](https://img-blog.csdnimg.cn/7038f33ebc9d43048c24edb280d04f46.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1:
NETiBA6Ziz5YWJ5rip5pqW56m65bGL,size_20,color_FFFFFF,t_70,g_se,x_16)
使用中文对测试用例进行命名:
win使用@pytest.mark.parametrize中ids,对用例命名为中文,导致编码乱码解决
解决方法一:
创建个pytest.ini 文件,输入以下代码:
PS:win电脑,在pytest.ini不要放入任何的中文,中文注释也是不可以的。
[pytest]
disable_test_id_escaping_and_forfeit_all_rights_to_community_support = True
想要输入中文的话,需要修改源代码配置文件:
每一个人的配置文件不一样,我的是/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/iniconfig,在__init__.py,找到其前面一行代码的 open() 函数,在 open 函数中增加 encoding=‘utf-8’ 参数,具体的操作如下图所示:
解决方法二:
创建conftest.py,这个文件可以放在该项目的同级目录或者是它的上级目录,但是不能放在下级目录下,在conftest.py文件中加入这部分代码:
from typing import List
def pytest_collection_modifyitems(
session:"Session",config:"Config",items:List["Item"]
) -> None:
for item in items:
item.name = item.name.encode('utf-8').decode('unicode-escape')
item._nodeid = item.nodeid.encode('utf-8').decode('unicode-escape')
(4)笛卡尔积
- 比如:
- a= [1,2,3]
- b=[a,b,c]
- 有以下几种形式组成:
- (1,a),(1,b),(1,c)
- (2,a),(2,b),(2,c)
- (3,a),(3,b),(3,c
实现笛卡尔积:
- 多次使用parametrize
- 同一个测试用例还可以同时添加多个@pytest.mark.parametrize装饰器,多个parametrize的左右元素相互组合(类似笛卡尔乘积),生成大量测试用例
import pytest
@pytest.mark.parametrize("wd",["appium","selenium","pytest"])
@pytest.mark.parametrize("code",["utf-8","gbk","gb2312"])
def test_dkej(wd,code):
print(f"wd: {wd}, code: {code}")
在这里插入图片描述
@pytest.mark.parametrize("a",[1,2])
@pytest.mark.parametrize("b",[8,10,11])
def test_food(a,b):
print(f"测试数据组合x: {a}, y: {b}")
- @pytest.fixture与pytest.mark.parametrize结合实现参数化
- 如果测试数据需要在fixture方法中使用,同时也需要在测试用例中使用,可以在使用parametrize的时候添加一个参数indirect=True,pytest可以实现将参数传入到fixture方法中,也可以在当前的测试用例中使用
- parametrize源码:def parametrize(self,argnames,argvalues,indirect=False,ids=None,scope=None):
- indirect参数设置True,pytest会把argnames当作函数去执行,将argvalues作为参数传入到argnames这个函数里。
import pytest
test_user_data = ['Tom', 'Jerry']
@pytest.fixture(scope="module")
def login_r(request):
# 通过request.param
user = request.param
print(f"\n登录用户:{user}")
return user
@pytest.mark.parametrize("login_r", test_user_data, indirect=True)
def test_login(login_r):
a = login_r
print(f"测试用例中login的返回值:{a}")
assert a != ""
运行结果:
test_parames.py::test_login[Tom]
登录用户:Tom PASSED 50%]测试用例中login的返回值:Tom
test_parames.py::test_login[Jerry]
登录用户:Jerry PASSED [100%]测试用例中login的返回值:Jerry
以上是pytest的参数化的学习记录,希望能够帮助到你们~~~