Python 数据驱动工具:DDT

发表于:2021-3-01 09:25

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:丹姐blog    来源:博客园

  背景
  python 的unittest 没有自带数据驱动功能。
  所以如果使用unittest,同时又想使用数据驱动,那么就可以使用DDT来完成。
  DDT是 “Data-Driven Tests”的缩写。
  使用方法
  dd.ddt:
  装饰类,也就是继承自TestCase的类。
  ddt.data:
  装饰测试方法。参数是一系列的值。
  ddt.file_data:
  装饰测试方法。参数是文件名。文件可以是json 或者 yaml类型。
  注意,如果文件以”.yml”或者”.yaml”结尾,ddt会作为yaml类型处理,其他所有文件都会作为json文件处理。
  如果文件中是列表,每个列表的值会作为测试用例参数,同时作为测试用例方法名后缀显示。
  如果文件中是字典,字典的key会作为测试用例方法的后缀显示,字典的值会作为测试用例参数。
  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)

      本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号