單元測試反應的是一種以測試為驅動的開發模式,最大的好處就是保證一個程序模塊的行為符合我們設計的測試用例,在將來修改的時候,可以極大程度保證該模塊行為仍然是正確的。
下面我編寫一個Dict來,這個類的行為和dict一直,同時可以通過屬性來訪問。
mydict.py文件:
class Dict(dict): def __init__(self,**kw): super().__init__(**kw) def __getattr(self,key): try: return self[key] except KeyError: raise AttributeError(r"'Dict' object has no attribute '%s'" % key) def __setattr__(self,key,value): self[key] = value
引入python自帶的unittest模塊,並需要繼承unittest.TestCase類,編寫mydict_test.py:
import unittest from mydict import Dict class TestDict(unittest.TestCase): def test_init(self): d = Dict(a=1,b = 'test') self.assertEqual(d.a,1) self.assertEqual(d.b,'test') self.assertTrue(isinstance(d,dict)) def test_ket(key): d = Dict() d['key'] = 'value' self.assertEqual(d.key,'value') def test_attr(self): d = Dict() d.key = 'value' self.assertTrue('key' in d) self.assertEqual(d['key'],'value') def test_keyerror(self): d = Dict() with self.assertRaises(KeyError): value = d['empty'] def test_attrerror(self): d = Dict() with self.assertRaises(AttributeError): value = d.empty
凡是以test開頭的方法都是測試方法,反之不是,測試時候不會執行。其中,unittest.TestCase提供很多內置的條件判斷,我們可以調用這些方法斷言輸出是否是我們所預計的。一般分為兩種,一種是assertEqual():斷言某兩個結果是否一致。一種是assertRaises():斷言是否是期待拋出的指定錯誤類型。
如何運行單元測試呢?
一種是在mydict_test.py文件最后添加2行代碼:
if __name__ == '__main__': unittest.main()
這樣我們可以直接運行mydict_test.py腳本。
一種是命令行增加參數 -m unittest 直接運行單元測試:
python -m unittest mydict_test
另外,可以通過在單元測試中增加兩個特殊函數setUp()和tearDown()函數,已實現在每調用一個測試方法的前后分別執行指定的動作,,其中setUp是在測試函數調用前執行,tearDown是在之后執行: