Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2446560
  • 博文数量: 328
  • 博客积分: 4302
  • 博客等级: 上校
  • 技术积分: 5486
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-01 11:14
个人简介

悲剧,绝对的悲剧,悲剧中的悲剧。

文章分类

全部博文(328)

文章存档

2017年(6)

2016年(18)

2015年(28)

2014年(73)

2013年(62)

2012年(58)

2011年(55)

2010年(28)

分类: Python/Ruby

2017-02-21 23:08:54

DDT (Data-Driven Tests) allows you to multiply one test case by running it with different test data, and make it appear as multiple test cases.

You can find (and fork) the project in .

Example usage

DDT consists of a class decorator ddt (for your TestCase subclass) and two method decorators (for your tests that want to be multiplied):

  • data: contains as many arguments as values you want to feed to the test.
  • file_data: will load test data from a JSON or YAML file.

Note

Only files ending with ”.yml” and ”.yaml” are loaded as YAML files. All other files are loaded as JSON files.

Normally each value within data will be passed as a single argument to your test method. If these values are e.g. tuples, you will have to unpack them inside your test. Alternatively, you can use an additional decorator, unpack, that will automatically unpack tuples and lists into multiple arguments, and dictionaries into multiple keyword arguments. See examples below.

This allows you to write your tests as:

  1. import unittest
  2. from ddt import ddt, data, file_data, unpack
  3. from test.mycode import larger_than_two, has_three_elements, is_a_greeting

  4. try:
  5.     import yaml
  6. except ImportError: # pragma: no cover
  7.     have_yaml_support = False
  8. else:
  9.     have_yaml_support = True
  10.     del yaml

  11. # A good-looking decorator
  12. needs_yaml = unittest.skipUnless(
  13.     have_yaml_support, "Need YAML to run this test"
  14. )


  15. class Mylist(list):
  16.     pass


  17. def annotated(a, b):
  18.     r = Mylist([a, b])
  19.     setattr(r, "__name__", "test_%d_greater_than_%d" % (a, b))
  20.     return r


  21. @ddt
  22. class FooTestCase(unittest.TestCase):
  23.     def test_undecorated(self):
  24.         self.assertTrue(larger_than_two(24))

  25.     @data(3, 4, 12, 23)
  26.     def test_larger_than_two(self, value):
  27.         self.assertTrue(larger_than_two(value))

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

  31.     @data(annotated(2, 1), annotated(10, 5))
  32.     def test_greater(self, value):
  33.         a, b = value
  34.         self.assertGreater(a, b)

  35.     @file_data("test_data_dict_dict.json")
  36.     def test_file_data_json_dict_dict(self, start, end, value):
  37.         self.assertLess(start, end)
  38.         self.assertLess(value, end)
  39.         self.assertGreater(value, start)

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

  43.     @file_data('test_data_list.json')
  44.     def test_file_data_json_list(self, value):
  45.         self.assertTrue(is_a_greeting(value))

  46.     @needs_yaml
  47.     @file_data("test_data_dict_dict.yaml")
  48.     def test_file_data_yaml_dict_dict(self, start, end, value):
  49.         self.assertLess(start, end)
  50.         self.assertLess(value, end)
  51.         self.assertGreater(value, start)

  52.     @needs_yaml
  53.     @file_data('test_data_dict.yaml')
  54.     def test_file_data_yaml_dict(self, value):
  55.         self.assertTrue(has_three_elements(value))

  56.     @needs_yaml
  57.     @file_data('test_data_list.yaml')
  58.     def test_file_data_yaml_list(self, value):
  59.         self.assertTrue(is_a_greeting(value))

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

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

  68.     @unpack
  69.     @data({'first': 1, 'second': 3, 'third': 2},
  70.           {'first': 4, 'second': 6, 'third': 5})
  71.     def test_dicts_extracted_into_kwargs(self, first, second, third):
  72.         self.assertTrue(first < third < second)

  73.     @data(u'ascii', u'non-ascii-\N{SNOWMAN}')
  74.     def test_unicode(self, value):
  75.         self.assertIn(value, (u'ascii', u'non-ascii-\N{SNOWMAN}'))

  76.     @data(3, 4, 12, 23)
  77.     def test_larger_than_two_with_doc(self, value):
  78.         """Larger than two with value {0}"""
  79.         self.assertTrue(larger_than_two(value))

  80.     @data(3, 4, 12, 23)
  81.     def test_doc_missing_args(self, value):
  82.         """Missing args with value {0} and {1}"""
  83.         self.assertTrue(larger_than_two(value))

  84.     @data(3, 4, 12, 23)
  85.     def test_doc_missing_kargs(self, value):
  86.         """Missing kargs with value {value} {value2}"""
  87.         self.assertTrue(larger_than_two(value))

  88.     @data([3, 2], [4, 3], [5, 3])
  89.     @unpack
  90.     def test_list_extracted_with_doc(self, first_value, second_value):
  91.         """Extract into args with first value {} and second value {}"""
  92.         self.assertTrue(first_value > second_value)

Where test_data_dict.json:

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

and test_data_list.json:

[ "Hello", "Goodbye" ] 
unsorted_list: 
- 10 
- 15 
- 12 
sorted_list: [ 15, 12, 50 ] 

and test_data_list.yaml:

- "Hello" 
- "Goodbye" 

And then run them with your favourite test runner, e.g. if you use nose:

$ nosetests -v test/test_example.py

The number of test cases actually run and reported separately has been multiplied.

DDT will try to give the new test cases meaningful names by converting the data values to valid python identifiers.

Repost from 
阅读(1419) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~