文章目录

  • 前言
  • 一、ddt简单介绍
  • 1.ddt是什么
  • 2.使用ddt的好处
  • 3.导入ddt模块
  • 4.四种模式
  • 二、ddt处理各种类型数据
  • 1.分析ddt工作原理
  • 2.ddt测试元祖数据
  • 2.1测试单组元素
  • 2.2测试多组未分解元素
  • 2.3测试多组分解元素
  • 3.ddt测试列表数据
  • 3.1多组未拆分数据
  • 3.2多组拆分数据
  • 3.3 复杂列表(含字典)未拆分数据
  • 3.4复杂列表(含字典)拆分
  • 4.ddt测试字典数据
  • 4.1多组数据未拆分
  • 4.2多组数据拆分
  • 5.ddt测试字典列表数据结合
  • 6.ddt测试外部数据
  • 总结



前言

在设计用例的时候,有些用例只是参数数据的输入不一样,比如登录这个功能,操作过程是一样的。如果用例重复去写操作过程会增加代码量,对应这种多组数据的测试用例,可以用数据驱动设计模式,一组数据对应一个测试用例,用例自动加载生成。(此前言引用自某教学视频老师的课程文档,前言不是我写的哈,文章正文才是哈)


提示:以下是本篇文章正文内容,下面案例可供参考

一、ddt简单介绍

1.ddt是什么

ddt:data driver tests ,数据驱动测试,是一种单元测试框架

2.使用ddt的好处

请参见本文章“前言”的内容

3.导入ddt模块

ddt属于第三方模块,需要安装,安装方法:
方法一:在cmd命令窗口中输入:pip install ddt
方法二:pycharm中打开终端,输入:pip install ddt

4.四种模式

ddt要与unittest单元测试框架一起结合使用
@ddt 引入ddt模块
@data 导入数据
@unpack 拆分数据
@file_data导入外部数据

下面直接通过具体的例子一一分析ddt的各种用法

二、ddt处理各种类型数据

需注意以下几点:
1.使用ddt模块要在测试类前用@ddt进行修饰
2.要导入测试数据需在测试用例(以test_开头的方法)前用@data修饰
3.若需对测试数据进行拆分需用@unpack修饰
4.若需导入外部数据需用@file_data修饰

1.分析ddt工作原理

仅通过一个小例子说明~

代码如下(示例):

import unittest
from ddt import ddt, data, unpack  # 根据需要导入相应的模块


@ddt
class TestDdt(unittest.TestCase):
    def setUp(self):
        print("setUp每个测试用例执行前都执行一次")

    def tearDown(self):
        print("tearDown每个测试用例执行后都执行一次")

    @data(1,2,"hello")
    def test_single_element(self, value):
        """
        测试单组元素
        :return:
        """
        print(value)
        self.assertEqual(value,1)

if __name__ == '__main__':
    unittest.main()

结果展示:

ddt使用 python python ddt详解_ddt使用 python


代码中@data(1,2,“hello”)传入了三个元素,故ddt自动生成了3个测试用用例。第一个测试用例将数据1和1进行比较,断言通过;第二个测试用例将数据2和1进行比较,断言失败;第三个测试用例将测试数据“hello”与1进行比较,断言失败

(是不是发现了什么?对!对于没有使用ddt的测试用例来说,一个test_开头的测试方法一次只能生成一个测试用例,但是!有了ddt之后,可以一次向测试方法中传入多个测试数据,而生成测试用例的个数则是根据@data中传入的测试数据的元素个数而定的)

2.ddt测试元祖数据

2.1测试单组元素

代码如下(示例):

import unittest
from ddt import ddt, data, unpack  # 根据需要导入相应的模块


@ddt
class TestDdt(unittest.TestCase):
    def setUp(self):
        print("setUp每个测试用例执行前都执行一次")

    def tearDown(self):
        print("tearDown每个测试用例执行后都执行一次")

    @data(1,2,"hello")
    def test_single_element(self, value):
        """
        测试单组元素
        :return:
        """
        print(value)
        

if __name__ == '__main__':
    unittest.main()

结果展示:

setUp每个测试用例执行前都执行一次
1
tearDown每个测试用例执行后都执行一次
setUp每个测试用例执行前都执行一次
2
tearDown每个测试用例执行后都执行一次
setUp每个测试用例执行前都执行一次
hello
tearDown每个测试用例执行后都执行一次

注意:上面的结果展示并不是控制台展示的全部结果内容,因为主要讨论的对于不同类型的数据ddt是如何处理的,所以我们只关注数据处理这一块(完整的结果类似于“1.分析ddt工作原理”中的结果展示)

2.2测试多组未分解元素

代码如下(示例):

import unittest
from ddt import ddt, data, unpack


@ddt
class TestDdt(unittest.TestCase):
    def setUp(self):
        print("setUp每个测试用例执行前都执行一次")

    def tearDown(self):
        print("tearDown每个测试用例执行后都执行一次")


    @data((1,2,3),(6,7,8))
    def test_multiple_elements(self,value):
        """
        测试多组未分解元素
        :param value:
        :return:
        """
        print(value)


if __name__ == '__main__':
    unittest.main()

结果展示:

setUp每个测试用例执行前都执行一次
(1, 2, 3)
tearDown每个测试用例执行后都执行一次
setUp每个测试用例执行前都执行一次
(6, 7, 8)
tearDown每个测试用例执行后都执行一次

2.3测试多组分解元素

代码如下(示例):

import unittest
from ddt import ddt, data, unpack


@ddt
class TestDdt(unittest.TestCase):
    def setUp(self):
        print("setUp每个测试用例执行前都执行一次")

    def tearDown(self):
        print("tearDown每个测试用例执行后都执行一次")

  
    @data((12,2,3),(24,6,7))
    @unpack	 # 对于要分解的元素需用@unpack修饰
    def test_mul_un_elements(self,value1,value2,value3):
        # print(value1,value2,value3)
        print(value1)
        print(value2)
        print(value3)


if __name__ == '__main__':
    unittest.main()

结果展示:

setUp每个测试用例执行前都执行一次
12
2
3
tearDown每个测试用例执行后都执行一次
setUp每个测试用例执行前都执行一次
24
6
7
tearDown每个测试用例执行后都执行一次

3.ddt测试列表数据

3.1多组未拆分数据

代码如下(示例):

import unittest
from ddt import ddt, data, unpack


@ddt
class TestDdt(unittest.TestCase):
    def setUp(self):
        print("setUp!")

    def tearDown(self):
        print("tearDown!")

    @data([1, 2, 3, 4], [5, 6, 7, 8])
    def test_single_list(self,value):
        print(value)


if __name__ == '__main__':
    unittest.main()

结果展示:

setUp!
[1, 2, 3, 4]
tearDown!
setUp!
[5, 6, 7, 8]
tearDown!

3.2多组拆分数据

代码如下(示例):

import unittest
from ddt import ddt, data, unpack


@ddt
class TestDdt(unittest.TestCase):
    def setUp(self):
        print("setUp!")

    def tearDown(self):
        print("tearDown!")

    @data([1, 2, 3, 4], [5, 6, 7, 8])
    # def test_single_list(self,value):
    #     print(value)
    @unpack
    def test_single_list(self, value1, value2, value3, value4):
        print(value1, value2, value3, value4)

if __name__ == '__main__':
    unittest.main()

结果展示:

setUp!
1 2 3 4
tearDown!
setUp!
5 6 7 8
tearDown!

3.3 复杂列表(含字典)未拆分数据

代码如下(示例):

import unittest
from ddt import ddt, data, unpack


@ddt
class TestDdt(unittest.TestCase):
    def setUp(self):
        print("setUp!")

    def tearDown(self):
        print("tearDown!")

    @data([{"username":"ljx","password":"123456"},{"addresss":"wuhan","phone":"152738748"}])
    def test_work(self,value):
        print(value)


if __name__ == '__main__':
    unittest.main()

结果展示:

setUp!
[{'username': 'ljx', 'password': '123456'}, {'addresss': 'wuhan', 'phone': '152738748'}]
tearDown!

3.4复杂列表(含字典)拆分

代码如下(示例):

import unittest
from ddt import ddt, data, unpack


@ddt
class TestDdt(unittest.TestCase):
    def setUp(self):
        print("setUp!")

    def tearDown(self):
        print("tearDown!")

    @data([{"username":"ljx","password":"123456"},{"addresss":"wuhan","phone":"152738748"}])
    @unpack
    def test_work(self,value1,value2):
        print(value1)
        print(value2)


if __name__ == '__main__':
    unittest.main()

结果展示:

setUp!
{'username': 'ljx', 'password': '123456'}
{'addresss': 'wuhan', 'phone': '152738748'}
tearDown!

4.ddt测试字典数据

4.1多组数据未拆分

代码如下(示例):

import unittest
from ddt import ddt, data, unpack


@ddt
class TestDdt(unittest.TestCase):
    def setUp(self):
        print("setUp每个测试用例执行前执行一次")

    def tearDown(self):
        print("tearDown每个测试用例执行后执行一次")

    @data({"username": "ljx", "password": "123456"}, {"addresss": "wuhan", "phone": "152738748"})
    def test_work(self, value):
        print(value)


if __name__ == '__main__':
    unittest.main()

结果展示:

setUp每个测试用例执行前执行一次
{'username': 'ljx', 'password': '123456'}
tearDown每个测试用例执行后执行一次
setUp每个测试用例执行前执行一次
{'addresss': 'wuhan', 'phone': '152738748'}
tearDown每个测试用例执行后执行一次

4.2多组数据拆分

注意:对于字典类型数据的拆分,需注意拆分时的形参必须与字典中的键一致(否则报错),并且对于多组字典进行拆分时,各个字典中包含的键必须一一对应(否则获取不到)

代码如下(示例):

import unittest
from ddt import ddt, data, unpack


@ddt
class TestDdt(unittest.TestCase):
    def setUp(self):
        print("setUp每个测试用例执行前执行一次")

    def tearDown(self):
        print("tearDown每个测试用例执行后执行一次")

    # @data({"username": "ljx", "password": "123456"}, {"username": "wuhan", "password": "152738748"})
    # @unpack
    # def test_work(self, value1, value2):  # 错误,对于字典的拆分,拆分参数必须与字典的键一致,否则报错
    #     print(value1)
    #     print(value2)

    @data({"username": "ljx", "password": "123456"}, {"username": "wuhan", "password": "152738748"})
    @unpack
    def test_work(self, username, password):
        print(username,password)

结果展示:

setUp每个测试用例执行前执行一次
ljx 123456
tearDown每个测试用例执行后执行一次
setUp每个测试用例执行前执行一次
wuhan 152738748
tearDown每个测试用例执行后执行一次

5.ddt测试字典列表数据结合

在实际应用中会存在数据比较多的情况,如果都直接把数据传入@data中会显得代码非常冗杂,以包含多个字典的列表数据为例,可将包含多个字典的元素存放在一个列表变量中,在@data中传入列表变量即可

代码如下(示例):

import unittest
from ddt import ddt, data, unpack


@ddt
class TestDdt(unittest.TestCase):
    def setUp(self):
        print("setUp!")

    def tearDown(self):
        print("tearDown!")

    test_data = [{"username": "ljx", "password": "123456"},
                 {"username": "wuhan", "password": "152738748"},
                 {"username": "1", "password": "18"}]

    @data(*test_data)	# *test_data将test_data变量拆包成3个字典元素
    def test_work(self, value):
        print(value.get("username"))
        print(value.get("password"))


if __name__ == '__main__':
    unittest.main()

结果展示:

setUp!
ljx
123456
tearDown!
setUp!
wuhan
152738748
tearDown!
setUp!
1
18
tearDown!

6.ddt测试外部数据

暂时还不清楚,后续再完善~


总结

小白一枚,如有错误,还请指出,谢谢~