DDT (数据驱动测试) 是一个 python 的第三方模块,使用这个模块可以扩展测试用例的数据。
举一个例子:做一个最常用的登录功能测试,不仅需要测试正常的登录情况,还要去测试异常的登录情况。按照平常的测试方法,测试用例的代码样例编写可能是这样的:
1 def test_login(self): 2 user_info=[('user1','123456'),('','123456'),('user1','')] 3 for use in user_info: 4 user_login(user[0],user1[1]) 5 self.assert()
上面测试场景中,使用到3组测试数据,分别是
1.用户名,密码正常的场景。
2.用户名为空,密码正常的场景。
3.用户名那个正常,密码为空的场景。
其实是3个测试用户。但是用上面的代码设计,运行完之后结果为1个测试用例。
跟预期的3个测试场景并不相符。
你可能会想到另外一种做法: 干脆写三个测试场景。
1 # 正常用户登录 2 def test_1login(self): 3 user_info = ('user1','123456') 4 login(user_info) 5 6 # 异常用户信息登录 7 def test_2login(self): 8 user_info = ('', '123456') 9 login(user_info) 10 11 # 用户异常信息登录 12 def test_3login(self): 13 user_info = ('user1','') 14 login(user_info)
这样的写法暂时可以满足需要。但是如果场景特别多。就需要定义很多testcase,对于以后的维护会造成很大的麻烦,并且都是重复函数调用。
其实对于这样的场景,理想的情况是,直接把测试数据放到文件中或者数据库中,定义读取数据函数,数据文件中有多少个数据,就自动执行多少个场景。后期通过维护数据文件来维护操作用例。
DDT 使用说明
ddt库主要就是来帮助解决这个问题的。
ddt GitHub:https://github.com/datadriventests/ddt
基本使用
用一个极其简单的示例,先来看下,平时测试多场景业务的弊端
1 import unittest 2 3 class TestWithoutDDT(unittest.TestCase): 4 5 def test_without_ddt(self): 6 for x in [1, -2, 3, 4, -5]: 7 self.assertGreater(x, 0) 8 9 10 if __name__ == '__main__': 11 unittest.main(verbosity=2)
执行结果:
test_without_ddt (__main__.TestWithoutDDT) ... FAIL
======================================================================
FAIL: test_without_ddt (__main__.TestWithoutDDT)
----------------------------------------------------------------------Traceback (most recent call last):
File "test1.py", line 8, in test_without_ddt
self.assertGreater(x, 0)
AssertionError: -2 not greater than 0
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (failures=1)
在取到值 -2 之后就不再往下执行。
而使用ddt:
(需要先安装ddt库)
1 import unittest 2 3 from ddt import ddt,data 4 5 @ddt 6 class TestWithoutDDT(unittest.TestCase): 7 8 @data(1, -2, 3, 4, -5) 9 def test_without_ddt(self,val): 10 self.assertGreater(val, 0) 11 12 if __name__ == '__main__': 13 unittest.main(verbosity=2)
执行结果:
test_without_ddt_1_1 (__main__.TestWithoutDDT) ... ok
test_without_ddt_2__2 (__main__.TestWithoutDDT) ... FAIL
test_without_ddt_3_3 (__main__.TestWithoutDDT) ... ok
test_without_ddt_4_4 (__main__.TestWithoutDDT) ... ok
test_without_ddt_5__5 (__main__.TestWithoutDDT) ... FAIL
======================================================================
FAIL: test_without_ddt_2__2 (__main__.TestWithoutDDT)
----------------------------------------------------------------------Traceback (most recent call last):
File "C:UserszyzhaoPycharmProjects emp_project
venvlibsite-packagesddt.py", line 145, in wrapper
return func(self, *args, **kwargs)
File "test1.py", line 8, in test_without_ddt
self.assertGreater(val, 0)
AssertionError: -2 not greater than 0
======================================================================
FAIL: test_without_ddt_5__5 (__main__.TestWithoutDDT)
----------------------------------------------------------------------Traceback (most recent call last):
File "C:UserszyzhaoPycharmProjects emp_project
venvlibsite-packagesddt.py", line 145, in wrapper
return func(self, *args, **kwargs)
File "test1.py", line 8, in test_without_ddt
self.assertGreater(val, 0)
AssertionError: -5 not greater than 0
----------------------------------------------------------------------
Ran 5 tests in 0.002s
FAILED (failures=2)
执行5条测试场景,符合我们的预期结果。另外,如果要添加新的数据,直接在 @data() 添加数据即可。
DDT从文件中读取数据
通过上面操作,如果改装登录测试用例,直接在 @data() 中将用户信息放入即可。但是这种方式维护数据还不是非常方便。因为在数据特别多之后 直接写在 @data() 还是不方便。
ddt 支持从yaml文件和json文件中读取数据。
json数据文件
1 data.json 2 { 3 "user_info_success": {"username": "user1","passwd": "123456"}, 4 "user_info_no_username": {"username": "","passwd": "123456"}, 5 "user_info_no_password": {"username": "user1","passwd": ""} 6 }
上面文定义了三行测试场景的数据
代码文件调用
1 import unittest 2 from ddt import ddt,data,file_data 3 4 5 @ddt 6 class TestWithDDT(unittest.TestCase): 7 8 @file_data('data.json') 9 def test_with_json(self,username,passwd): 10 print(username,passwd) 11 12 if __name__ == '__main__': 13 unittest.main(verbosity=2)
添加装饰器 @file_data
testcase中 username,passwd变量对应的分别是 json数据文件中的 username, passwd 的值。
(备注:需要主要的是 username,passwd 与json数据文件中是一一对应的关系。)
yaml数据文件
读取yaml文件需要安装支持读取yaml的库。读取yaml 需要安装yaml库
pip install pyyaml
定义data.yaml 文件
1 user_info_success: 2 username: "user1" 3 passwd: "123456" 4 5 user_info_no_username: 6 username: "" 7 passwd: "123456" 8 9 user_info_no_passwd: 10 username: "user1" 11 passwd: ""
代码调用
1 import unittest 2 from ddt import ddt,data,file_data 3 4 @ddt 5 lass TestWithoutDDT(unittest.TestCase): 6 7 @file_data('data.yaml') 8 def test_with_yaml(self,username,passwd): 9 print(username,passwd) 10 11 12 if __name__ == '__main__': 13 unittest.main(verbosity=2)
扩展
1.yaml语言教程:http://www.ruanyifeng.com/blog/2016/07/yaml.html
2.python解析yaml数据文件:https://pyyaml.org/wiki/PyYAMLDocumentation
3.python 装饰器:https://www.yuque.com/funcat/python.autotesting/vhgbdw