背景
python 的unittest 沒有自帶資料驅動功能,
所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成,
DDT是 “Data-Driven Tests”的縮寫,
資料:http://ddt.readthedocs.io/en/latest/
使用方法
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)
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/1012.html
標籤:面向對象
上一篇:談談我對C# 多型的理解