Python 数据驱动工具:DDT

背景

python 的unittest 没有自带数据驱动功能。python

因此若是使用unittest,同时又想使用数据驱动,那么就能够使用DDT来完成。json

DDT是 “Data-Driven Tests”的缩写。数据结构

资料:http://ddt.readthedocs.io/en/latest/post

使用方法

dd.ddt:

装饰类,也就是继承自TestCase的类。测试

ddt.data:

装饰测试方法。参数是一系列的值。spa

ddt.file_data:

装饰测试方法。参数是文件名。文件能够是json 或者 yaml类型。code

注意,若是文件以”.yml”或者”.yaml”结尾,ddt会做为yaml类型处理,其余全部文件都会做为json文件处理。blog

若是文件中是列表,每一个列表的值会做为测试用例参数,同时做为测试用例方法名后缀显示。继承

若是文件中是字典,字典的key会做为测试用例方法的后缀显示,字典的值会做为测试用例参数。three

ddt.unpack:

传递的是复杂的数据结构时使用。好比使用元组或者列表,添加unpack以后,ddt会自动把元组或者列表对应到多个参数上。字典也能够这样处理。参见下面的示例2.

测试用例方法名生成规则

使用ddt后,会产生一个新的测试用例方法名:以前的测试用例方法名_ordinal_data

以前的测试用例方法名:即定义的测试用例方法名。好比def test_large(),这里就是test_large

ordinal:整数,从1开始递加。

data:若是传递过来的数据存在__name__属性,则这里就是该数据的__name__值。若是未定义__name__属性,ddt会尽可能将传递过来的数据转化为python标识符,做为data显示。好比(3,2)就转化为3_2。须要注意的是,若是数据是字典,则这里就是字典的key。

使用示例

1. data直接放入数值

须要导入ddt包,而后再TestCase类上采用@ddt进行装饰,测试方法上装饰@data()。

data能够是数值,也能够是字符串。

复制代码
import unittest
from ddt import ddt, data
from ddt_demo.mycode import larger_than_two

@ddt
class FooTestCase(unittest.TestCase):
    
    @data(3, 4, 12, 23)
    def test_larger_than_two(self, value):
        self.assertTrue(larger_than_two(value))

    @data(1, -3, 2, 0)
    def test_not_larger_than_two(self, value):
        self.assertFalse(larger_than_two(value))

    @data(u'ascii', u'non-ascii-\N{SNOWMAN}')
    def test_unicode(self, value):
        self.assertIn(value, (u'ascii', u'non-ascii-\N{SNOWMAN}'))
        
if __name__=='__main__':
    unittest.main(verbosity=2)
复制代码

输出以下:

复制代码
test_larger_than_two_1_3 (__main__.FooTestCase) ... ok
test_larger_than_two_2_4 (__main__.FooTestCase) ... ok
test_larger_than_two_3_12 (__main__.FooTestCase) ... ok
test_larger_than_two_4_23 (__main__.FooTestCase) ... ok
test_not_larger_than_two_1_1 (__main__.FooTestCase) ... ok
test_not_larger_than_two_2__3 (__main__.FooTestCase) ... ok
test_not_larger_than_two_3_2 (__main__.FooTestCase) ... ok
test_not_larger_than_two_4_0 (__main__.FooTestCase) ... ok
test_unicode_1_ascii (__main__.FooTestCase) ... ok
test_unicode_2_non_ascii__ (__main__.FooTestCase) ... ok

----------------------------------------------------------------------
Ran 10 tests in 0.001s

OK
复制代码

能够看到上面只写了3个测试方法,可是最后run了10个用例。

这里测试方法后会被ddt加一个后缀,ddt会尝试把测试数据转化为后缀附在测试方法后,组成一个新的名字。

2. data放入复杂的数据结构

使用复杂的数据结构时,须要用到@unpack,同时测试方法的参数须要使用对应的多个,好比下面的frist_value 以及 second_value。

复制代码
import unittest
from ddt import ddt, data,unpack

@ddt
class FooTestCase(unittest.TestCase):

    @data((3, 2), (4, 3), (5, 3))
    @unpack
    def test_tuples_extracted_into_arguments(self, first_value, second_value):
        self.assertTrue(first_value > second_value)

    @data([3, 2], [4, 3], [5, 3])
    @unpack
    def test_list_extracted_into_arguments(self, first_value, second_value):
        self.assertTrue(first_value > second_value)

    @unpack
    @data({'first': 1, 'second': 3, 'third': 2},
          {'first': 4, 'second': 6, 'third': 5})
    def test_dicts_extracted_into_kwargs(self, first, second, third):
        self.assertTrue(first < third < second)
        
if __name__=='__main__':
    unittest.main(verbosity=2)
复制代码

执行以后,所有pass。

3. 使用json文件

新建文件 test_data_list.json:

[
    "Hello",
    "Goodbye"
]

新建文件  test_data_dict.json:

{
    "unsorted_list": [ 10, 12, 15 ],
    "sorted_list": [ 15, 12, 50 ]
}

新建测试脚本ddt_test.py:

复制代码
import unittest
from ddt import ddt, file_data
from ddt_demo.mycode import has_three_elements,is_a_greeting

@ddt
class FooTestCase(unittest.TestCase):

    @file_data('test_data_dict.json')
    def test_file_data_json_dict(self, value):
        self.assertTrue(has_three_elements(value))

    @file_data('test_data_list.json')
    def test_file_data_json_list(self, value):
        self.assertTrue(is_a_greeting(value))
        
if __name__=='__main__':
    unittest.main(verbosity=2)
复制代码

4. 使用yaml文件

新建文件 test_data_list.yaml:

- "Hello"
- "Goodbye"

新建文件 test_data_dict.yaml:

复制代码
unsorted_list:
  - 10
  - 15
  - 12

sorted_list: [ 15, 12, 50 ]
复制代码

新建测试脚本ddt_test.py:

复制代码
import unittest
from ddt import ddt, file_data
from ddt_demo.mycode import has_three_elements,is_a_greeting

@ddt
class FooTestCase(unittest.TestCase):

    @file_data('test_data_dict.yaml')
    def test_file_data_yaml_dict(self, value):
        self.assertTrue(has_three_elements(value))

    @file_data('test_data_list.yaml')
    def test_file_data_yaml_list(self, value):
        self.assertTrue(is_a_greeting(value))
        
if __name__=='__main__':
    unittest.main(verbosity=2)
复制代码
相关文章
相关标签/搜索