一.概念
参数化,就是把测试过程中的数据提取出来,通过参数传递不同的数据来驱动用例运行。其实也就是数据驱动的概念。
可以使用 @pytest.mark.parametrize(argnames, argvalues) 装饰器达到批量传送参数的目的
在 unittest 中,使用ddt库配合unittest实现数据驱动。在pytest中并不需要额外的库,通过pytest.mark.parametrize()即可实现参数化。
parametrize()的第一个参数是用逗号分割的字符串列表,第二个参数是一个值列表
pytest有三种传参方式:
@pytest.mark.parametrize() 通过装饰器方式进行参数化(最常使用)
pytest.fixture()方式进行参数化,fixture装饰的函数可以作为参数传入其他函数
conftest.py文件中存放参数化函数,可作用于模块内的所有测试用例
二.单个参数
test_params
import pytest
def add(a,b):
return a+b
class TestParams:
@pytest.mark.parametrize('a',[1,2,3,4,5])
def test_par1(self,a):
assert add(a,1)==a+1
命令行执行:
pytest
特别注意:
@pytest.mark.parametrize() 装饰器接收两个参数,
第一个参数是以字符串的形式标识用例函数的参数,
第二个参数以列表或元组的形式传递测试数据。
三.多个参数
案例1
test_params
import pytest
def add(a,b):
return a+b
class TestParams:
@pytest.mark.parametrize('a,b,c',[[1,2,3],[3,4,5],[1,3,4],[2,5,7]])
def test_par1(self,a,b,c):
assert add(a,b)==c
执行命令
特别注意:
多个参数之间要用逗号分隔
参数名称和个数要一一对应
案例2:使用py文件存放测试数据
测试数据
login_data_list = [
{'username': 'kobe', 'password': 666666, 'expect': '登录成功'},
{'username': 'kobe', 'password': 111111, 'expect': '用户名或者密码错误'},
{'username': '', 'password': 666666, 'expect': ''},
]
test_work
import pytest
from data.data1 import login_data_list
class TestParams:
@pytest.mark.parametrize('test_data',login_data_list)
def test_par1(self,test_data):
username=test_data['username']
password=test_data['password']
assert username=='kobe' and password==666666
测试结果
案例3:使用yaml文件存放测试数据
yaml文件
-
name: '账号密码正确'
username: 'kobe'
password: 666666
-
name: '用户名为空'
username:
password: 666666
-
name: '用户名或者密码错误'
username: 'james'
password: 666666
read_yaml.py
import os
import yaml
def read_yaml(yaml_file_path):
try:
with open( yaml_file_path, "r",encoding="utf-8") as f:
value = yaml.load(stream=f, Loader=yaml.FullLoader)
except:
with open(yaml_file_path, "r",encoding="gbk") as f:
value = yaml.load(stream=f, Loader=yaml.FullLoader)
print(value)
return value
if __name__ == '__main__':
read_yaml(r'D:\project_development\api_pytest\data\test_yaml.yaml')
读取结果:
[{'name': '账号密码正确', 'username': 'kobe', 'password': 666666}, {'name': '用户名为空', 'username': None, 'password': 666666}, {'name': '用户名或者密码错误', 'username': 'james', 'password': 666666}]
test_yaml_work.py
import pytest
from utils.read_yaml import read_yaml
class TestParams:
@pytest.mark.parametrize('case',read_yaml(r'D:\project_development\api_pytest\data\test_yaml.yaml'))
def test_login(self,case):
username=case['username']
password=case['password']
assert username=='kobe' and password==666666
执行测试:
D:\project_development\api_pytest>pytest testcases/params/test_yaml_work.py
案例4:使用json文件存放测试数据
test_json.json
[
{
"name": "账号密码正确",
"username": "kobe",
"password": 666666
},
{
"name": "用户名为空",
"username": "",
"password": 666666
},
{
"name": "用户名或者密码错误",
"username": "james",
"password": 666666
}
]
read_json.py
import os
import json
def read_json(json_file_path):
try:
with open(json_file_path, "r", encoding="utf-8") as f:
datas = json.load(f)
except:
with open(json_file_path, "r", encoding="gbk") as f:
datas = json.load(f)
if not isinstance(datas, list):
raise ValueError('json文件内的用例数据格式不符护规范')
print(datas)
return datas
if __name__ == '__main__':
read_json(r'D:\project_development\api_pytest\data\test_json.json')
读取结果:
[{'name': '账号密码正确', 'username': 'kobe', 'password': 666666}, {'name': '用户名为空', 'username': '', 'password': 666666}, {'name': '用户名或者密码错误', 'username': 'james', 'password': 666666}]
test_json_work.py
import pytest
from utils.read_yaml import read_yaml
class TestParams:
@pytest.mark.parametrize('case',read_yaml(r'D:\project_development\api_pytest\data\test_yaml.yaml'))
def test_login(self,case):
username=case['username']
password=case['password']
assert username=='kobe' and password==666666
四.对测试类参数化
测试类的参数化,其实际上也是对类中的测试方法进行参数化。类中的测试方法的参数必须与@pytest.mark.parametrize()中的标识的参数个数一致。
案例1
import pytest
def add(a,b):
return a+b
@pytest.mark.parametrize('a,b,c',[[1,2,3],[1,3,4],[2,5,7]])
class TestParams:
def test_par1(self,a,b,c):
assert add(a,b)==c
def test_par2(self,a,b,c):
assert add(a,b)==c
执行结果