python学习杂记-DDT驱动测试

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:\Users\zyzhao\PycharmProjects\temp_project\

venv\lib\site-packages\ddt.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:\Users\zyzhao\PycharmProjects\temp_project\

venv\lib\site-packages\ddt.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

 

posted @ 2020-06-30 13:38  -Ruirui-  阅读(518)  评论(0编辑  收藏  举报