DDT:Data Driver Tests
数据驱动ddt可以实现测试数据与测试脚本的分离,通过ddt来将测试数据加载到脚本中。采用数据驱动设计模式使一组数据对应一个测试用例,通过数据的改变从而驱动自动化测试的执行。既能减少代码量,也能降低代码的维护成本。
ddt 是第三方模块,需安装:
pip install ddt
官网:https://ddt.readthedocs.io/en/latest/
通常情况下,data中的数据按照一个参数传递给测试用例,如果data中含有多个数据,如元组,列表,字典等数据,需要自行在脚本中对数据进行分解或者使用unpack分解数据。
@ddt 类装饰器,用来标记当前类使用ddt数据驱动
@data 函数装饰器,用来给函数传递数据
@unpack 函数装饰器,用来对传递的数据进行解包,解列表、元组、字典
@file_data 函数装饰器,用来直接读取yaml,json格式的文件数据 读取获取的数据是字典列表
@data(a,b)
那么a和b各运行一次用例
@data([a,b],[c,d])
如果没有@unpack,那么[a,b]当成一个参数传入用例运行
如果有@unpack,那么[a,b]被分解开,按照用例中的两个参数传递
import unittest
from ddt import ddt, data, unpack
case_data = [{"url": "www.baidu.com", "data": "test1"},
{"url": "www.baidu.com", "data": "test2"},
{"url": "www.baidu.com", "data": "test3"}]
@ddt
class TestDemo(unittest.TestCase):
@data(*case_data) #在测试函数上使用@data(*case_data)进行数据解压,然后每一个元素传入测试函数
def test_case(self, case):
print(case)
运行结果:
Ran 3 tests in 0.005s
OK
{‘url’: ‘www.baidu.com’, ‘data’: ‘test1’}
{‘url’: ‘www.baidu.com’, ‘data’: ‘test2’}
{‘url’: ‘www.baidu.com’, ‘data’: ‘test3’}
import unittest
from ddt import ddt, data, unpack
@ddt
class MyTesting(unittest.TestCase):
@data([1, 2, 3]) #没有@unpack,那么当成一个参数[1, 2, 3]
def test_1(self, value):
print(f'test_1:value={value}')
@data(4,5,6) #三个元素4,5,6
def test_2(self, a):
print(f'test_2:a={a}')
@data([3, 2, 1], [5, 3, 2], [10, 4, 6])
@unpack #有@unpack,那么分解成3个参数传入用例运行:3, 2, 1是3个参数
def test_minus(self, a, b, expected):
actual = int(a) - int(b)
expected = int(expected)
self.assertEqual(actual, expected)
@data([2, 3], [4, 5]) #没有@unpack,那么当成一个参数:[2, 3]是一个参数,[4, 5]是一个参数
def test_compare(self, a):
print(f'test_compare:a={a}')
if __name__ == '__main__':
unittest.main(verbosity=2)
执行结果为:
在testdata package下新建testdata1.yml文件,文件中写入测试数据如下:
#格式要求:
#"-"表示一个列表
#用tab键缩进
-
name: 'testyy'
age: 18
-
name: 'testzz'
age: 20
test_ddt.py文件中修改测试代码如下:
import unittest
import ddt # 导入ddt
import yaml
@ddt.ddt # 声明我们要用它
class Test_ddt(unittest.TestCase):
def setUp(self):
print("Before every test case!")
@ddt.file_data("..\\testdata\\testdata1.yml") #括号里写yml文件的相对路径
def test_002(self,name,age):
print('name is:' +str(name))
print('age is:' + str(age))
if __name__ == '__main__':
unittest.main()
执行结果为:
可以看到yml文件中我们定义了2组数据,用例总共执行了2次,按顺序每次取一组数据作为入参。
在testdata package下新建testdata2.json文件,文件中写入测试数据如下:
{
"student1": {
"name": "小明",
"age": 12
},
"student2": {
"name": "小张",
"age": 20
}
}
test_ddt.py文件中修改测试代码如下:
import unittest
import ddt # 导入ddt
import yaml
@ddt.ddt # 声明我们要用它
class Test_ddt(unittest.TestCase):
def setUp(self):
print("Before every test case!")
@ddt.file_data("..\\testdata\\testdata2.json")#括号里写json文件的相对路径
def test_003(self,name,age):
print("name is:"+str(name))
print("age is:" +str(age))
if __name__ == '__main__':
unittest.main()
执行结果为:
综上,从脚本文件中直接获取测试数据、从yml文件获取测试数据、从Json文件获取测试数据,应该已经可以满足自动化测试需要了。