python - unittest 單元測試學習

  單元測試

單元測試是用來對一個模塊、一個函數或者一個類進行正確性檢驗的測試工做html

好比對Python中的abs 的測試python

輸入正數: 好比 1, 2, 3, 返回值不變數據庫

輸入負數: 好比 -1, -2, -3, 返回值是自己取反函數

輸入0: 好比 0, 返回值0單元測試

把上面的測試用例放到一個測試模塊裏,就是一個完整的單元測試。學習

若是單元測試經過,說明咱們測試的這個函數可以正常工做。若是單元測試不經過,要麼函數有bug,要麼測試條件輸入不正確,總之,須要修復使單元測試可以經過。測試

單元測試經過後有什麼意義呢?若是咱們對abs()函數代碼作了修改,只須要再跑一遍單元測試,若是經過,說明咱們的修改不會對abs()函數原有的行爲形成影響,若是測試不經過,說明咱們的修改與原有行爲不一致,要麼修改代碼,要麼修改測試。spa

這種以測試爲驅動的開發模式最大的好處就是確保一個程序模塊的行爲符合咱們設計的測試用例。在未來修改的時候,能夠極大程度地保證該模塊行爲仍然是正確的。設計

咱們來編寫一個Dict類,這個類的行爲和dict一致,可是能夠經過屬性來訪問,用起來就像下面這樣:code

>>> d = Dict(a=1, b=2)
>>> d['a']
1
>>> d.a
1

Dict 類的具體實現:

 1 class Dict(dict):
 2     def __init__(self,**kw):
 3         super(Dict,self).__init__(**kw)
 4 
 5     def __getattr__(self, key):
 6         try:
 7             return self[key]
 8         except KeyError:
 9             raise AttributeError(r"'Dict' object has no attribute '%s'" % key)
10 
11     def __setattr__(self, key, value):
12         self[key] = value

 

  unittest.TestCase

編寫單元測試時,咱們須要編寫一個測試類,從unittest.TestCase繼承。

以test開頭的方法就是測試方法,不以test開頭的方法不被認爲是測試方法,測試的時候不會被執行。

對每一類測試都須要編寫一個test_xxx()方法。因爲unittest.TestCase提供了不少內置的條件判斷,咱們只須要調用這些方法就能夠斷言輸出是不是咱們所指望的。最經常使用的斷言就是assertEquals():

1 self.assertEquals(abs(-1), 1) # 斷言函數返回的結果與1相等

另外一種重要的斷言就是期待拋出指定類型的Error,好比經過d['empty']訪問不存在的key時,斷言會拋出KeyError:

1 with self.assertRaises(KeyError):
2     value = d['empty']

而經過d.empty訪問不存在的key時,咱們期待拋出AttributeError:

1 with self.assertRaises(AttributeError):
2     value = d.empty

setUp與tearDown 能夠在單元測試中編寫兩個特殊的setUp()和tearDown()方法。這兩個方法會分別在每調用一個測試方法的先後分別被執行。

setUp()和tearDown()方法有什麼用呢?設想你的測試須要啓動一個數據庫,這時,就能夠在setUp()方法中鏈接數據庫,在tearDown()方法中關閉數據庫,這樣,沒必要在每一個測試方法中重複相同的代碼:

1 class TestDict(unittest.TestCase):
2 
3     def setUp(self):
4         print 'setUp...'
5 
6     def tearDown(self):
7         print 'tearDown...'

能夠再次運行測試看看每一個測試方法調用先後是否會打印出setUp...和tearDown...。

  測試類的具體實現:

 1 import unittest
 2 from Dict import Dict
 3 
 4 class TestDict(unittest.TestCase):
 5 
 6     def setUp(self):
 7         print 'setUp...'
 8 
 9     def tearDown(self):
10         print 'tearDown...'
11 
12     def test_init(self):
13         d = Dict(a=1, b='test')
14         self.assertEquals(d.a, 1)
15         self.assertEquals(d.b, 'test')
16         self.assertTrue(isinstance(d, dict))
17 
18     def test_key(self):
19         d = Dict()
20         d['key'] = 'value'
21         self.assertEquals(d.key, 'value')
22 
23     def test_attr(self):
24         d = Dict()
25         d.key = 'value'
26         self.assertTrue('key' in d)
27         self.assertEquals(d['key'], 'value')
28 
29     def test_keyerror(self):
30         d = Dict()
31         with self.assertRaises(KeyError):
32             value = d['empty']
33 
34     def test_attrerror(self):
35         d = Dict()
36         with self.assertRaises(AttributeError):
37             value = d.empty
38 
39 if __name__ == '__main__':
40     unittest.main()

  注意:

單元測試能夠有效地測試某個程序模塊的行爲,是將來重構代碼的信心保證。

單元測試的測試用例要覆蓋經常使用的輸入組合、邊界條件和異常。

單元測試代碼要很是簡單,若是測試代碼太複雜,那麼測試代碼自己就可能有bug。

單元測試經過了並不意味着程序就沒有bug了,可是不經過程序確定有bug。

版權全部,文章來源:http://www.cnblogs.com/sagecheng/p/5969070.html 

我的能力有限,本文內容僅供學習、探討,歡迎指正、交流。

 

  參考資料:

python 基礎教程:http://www.runoob.com/python/python-tutorial.html

相關文章
相關標籤/搜索