# Data driven #
讲到数据驱动,通常我们会想到ddt,没错它是数据驱动的一种形式,另外还有很多不同形式的数据驱动。而不同的测试框架所采用的数据驱动形式也不一样,它们主要是用来解决自动化中测试用例的参数化,本文主要介绍unitest和 pytest的数据驱动。
parameterized
★
NEWS
★
parameterized模块,顾名思义就是用来参数化的,安装时只需pip install parameterized即可,
@parameterized.expand必须要求参数是一个iterable可迭代对象。
from parameterized import parameterized,paramdatas = [{'first': 1, 'second': 3, 'third': 5},{'first': 4, 'second': 7, 'third': 8},{"first": {'username': '15669910105'}}]#也可使用json.dumps(data)@parameterized.expand(param(data) for data in datas)def test_1(data):print(data)

@ddt
★
NEWS
★
unittest的数据驱由@ddt装饰器实现测试用例参数化。
ddt模块,安装时只需pip install ddt即可;ddt包含类的装饰器ddt和两个方法装饰器@data、@file_data。
@data(a,b)
那么a和b各运行一次用例
@data([a,d],[c,d])
如果没有@unpack,那么[a,b]当成一个参数传入用例运行
如果有@unpack,那么[a,b]被分解开,按照用例中的两个参数传递
import unittestfrom ddt import ddt,unpack,data,file_datadatas = [{'first': 1, 'second': 3, 'third': 5},{'first': 4, 'second': 7, 'third': 8},{"first": {'username': '15669910105'}}]@ddtclass TestCases(unittest.TestCase):"""datas可以是列表,也可以是元祖@data(datas) 取的是整改列表@data(*datas) 取的是列表元素@data(*datas)@unpack 取的是列表元素中子元素"""@data(datas)def test_dicts(self,value):print(value)@data(*datas)def test_dict(self,value):print(value)@data(*datas)@unpackdef test_dict_element(self, first, second, third):print(first,second,third)if __name__ == '__main__':unittest.main()

@pytest.mark.parametrize
★
NEWS
★
pytest的数据驱由@pytest.mark.parametrize装饰器实现测试用例参数化。
无需安装模块,采用pytest内部parametrize装饰器。
@pytest.mark.parametrize,里面写两个参数
第一个参数是字符串,多个参数中间用逗号隔开
第二个参数是list,多组数据用元祖类型
import pytestdatas = [{'first': 1, 'second': 3, 'third': 5},{'first': 4, 'second': 7, 'third': 8},#{"first": {'username': '15669910105'}}]@pytest.mark.parametrize("data",datas)def test_1(data):print(data)@pytest.mark.parametrize("data1,data2,data3",datas)def test_2(data1,data2,data3):print(data1,data2,data3)if __name__ == '__main__':pytest.main(['-s', 'test.py'])

我们还可以给测试用例带上名称,使用@pytest.mark.parametrize中ids字段,代码如下。
import pytestdatas = [{'name': 'x', 'first': 1, 'second': 3, 'third': 5},{'name': 'y', 'first': 4, 'second': 7, 'third': 8},{'name': 'z', "first": {'username': '15669910105'}}]@pytest.mark.parametrize("data", datas, ids=[data['name'] for data in datas])def test_1(data):print(data)if __name__ == '__main__':pytest.main(['-s', 'test.py'])

@pytest.fixture
★
NEWS
★
pytest的数据驱由@pytest.fixture装饰器实现参数函数,
无需安装模块,采用pytest内部fixture装饰器。
fixture是可以有返回值的,如果没return默认返回None。用例调用fixture的返回值,直接就是把fixture的函数名称当成变量传入。
import pytestdatas = [{'name': 'x','first': 1, 'second': 3, 'third': 5},{'name': 'y','first': 4, 'second': 7, 'third': 8},{'name': 'z',"first": {'username': '15669910105'}}]@pytest.fixture(params=datas,ids=[data['name'] for data in datas])def fixture_param(request): #参数化return request.paramdef test_1(fixture_param): #调用print(fixture_param)if __name__ == '__main__':pytest.main(['-s', 'test.py'])

@pytest.mark.parametrize&@pytest.fixture
★
NEWS
★
parametrize和fixture两者还可以结合使用,不过会生成笛卡尔集用例集。
import pytestdatas = [{'name': 'x','first': 1, 'second': 3, 'third': 5},{'name': 'y','first': 4, 'second': 7, 'third': 8},{'name': 'z',"first": {'username': '15669910105'}}]@pytest.fixture(params=datas,ids=[data['name'] for data in datas])def fixture_param(request): #参数化return request.param@pytest.mark.parametrize("a",[1,2])def test_2(a,fixture_param): #调用print(a,fixture_param)if __name__ == '__main__':pytest.main(['-s', 'test.py'])


微信公众号 | 湖边小




