Python自帶的unittest和test兩個模塊為編寫test case提供了很靈活的支持,最常用的情況就是繼承自unittest.TestCase類,然后對每一個要進(jìn)行測試的行為寫一個test_開頭的類成員函數(shù),最后可以利用test.test_support.run_unittest函數(shù)跑所有的test case.
在某種情況下,可能需要用不同的參數(shù)組合測試同樣的行為,這些行為要么很耗時間(譬如下載數(shù)據(jù)),要么是你希望從test case的執(zhí)行結(jié)果上知道在測試什么,而不是單單得到一個大的 test case;此時如果僅僅寫一個test case并用內(nèi)嵌循環(huán)來進(jìn)行,那么其中一個除了錯誤,很難從測試結(jié)果里邊看出來。
問題的關(guān)鍵在于是否有辦法根據(jù)輸入?yún)?shù)的不同組合產(chǎn)生出對應(yīng)的test case;譬如你有10組數(shù)據(jù),那么得到10個test case,當(dāng)然不適用純手工的方式寫那么多個test_成員函數(shù)。
一種可能的思路是不利用unittest.TestCase這個類框中的test_成員函數(shù)的方法,而是自己寫runTest這個成員函數(shù),那樣會有一些額外的工作,而且看起來不是那么“智能”,如果目的是讓框架自動調(diào)用testcase.
自然的思路就是
-
利用setattr來自動為已有的TestCase類添加成員函數(shù)
-
為了使這個方法湊效,需要用類的static method來生成decorate類的成員函數(shù),并使該函數(shù)返回一個test函數(shù)對象出去
-
在某個地方注冊這個添加test成員函數(shù)的調(diào)用(只需要在實際執(zhí)行前就可以,可以放在模塊中自動執(zhí)行亦可以手動調(diào)用)
最后的代碼就有了:
01 import unittest
02 from test import test_support
03
04 def MyTestCase(unittest.TestCase):
05 def setUp(self):
06 #some setup code
07 pass
08
09 def clear(self):
10 #some cleanup code
11 pass
12
13 def action(self, arg1, arg2):
14 pass
15
16 @staticmethod
17 def getTestFunc(arg1, arg2):
18 def func(self):
19 self.actions(arg1, arg2)
20 return func
21
22 def __generateTestCases():
23 arglists = [('arg11', 'arg12'), ('arg21', 'arg22'), ('arg31', 'arg32')]
24 for args in arglists:
25 setattr(MyTestCase, 'test_func_%s_%s'%(args[0], args[1]),
26 MyTestCase.getTestFunc(*args) )
27 __generateTestCases()
28
29 def test_main():
30 test_support.run_unittest(MyTestCase)
如此,添加一個新的可變參數(shù)組合,就會新生成一個test case, 只需要將參數(shù)組合添加到arglist中就可以了。