• 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: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

  • 相关阅读:
    shell 字符串切分成数组
    RDD关键性能考量之 内存管理
    RDD关键性能考量之 序列化格式
    【转】Linux ln(link) 命令详解
    【转】redis配置认证密码
    【转】MongoDB 知识要点一览
    RDD关键性能考量之 并行度
    使用thumbnailator不按照比例,改变图片的大小
    Linux服务器redhat配置本地yum源
    Oracle表字段的增删改和重命名
  • 原文地址:https://www.cnblogs.com/RuiRuia/p/13213262.html
Copyright © 2020-2023  润新知