單元測試是用來對乙個模組、乙個函式或者乙個類進行正確性檢驗的測試工作
比如對python中的abs 的測試
輸入正數: 比如 1, 2, 3, 返回值不變
輸入負數: 比如 -1, -2, -3, 返回值是本身取反
輸入0: 比如 0, 返回值0
把上面的測試用例放到乙個測試模組裡,就是乙個完整的單元測試。
如果單元測試通過,說明我們測試的這個函式能夠正常工作。如果單元測試不通過,要麼函式有bug,要麼測試條件輸入不正確,總之,需要修復使單元測試能夠通過。
單元測試通過後有什麼意義呢?如果我們對abs()函式**做了修改,只需要再跑一遍單元測試,如果通過,說明我們的修改不會對abs()函式原有的行為造成影響,如果測試不通過,說明我們的修改與原有行為不一致,要麼修改**,要麼修改測試。
這種以測試為驅動的開發模式最大的好處就是確保乙個程式模組的行為符合我們設計的測試用例。在將來修改的時候,可以極大程度地保證該模組行為仍然是正確的。
我們來編寫乙個dict類,這個類的行為和dict一致,但是可以通過屬性來訪問,用起來就像下面這樣:
>>> d = dict(a=1, b=2)>>> d['a'
]1>>>d.a
1
dict 類的具體實現:
1class
dict(dict):
2def
__init__(self,**kw):
3 super(dict,self).__init__(**kw)45
def__getattr__
(self, key):
6try:7
return
self[key]
8except
keyerror:
9raise attributeerror(r"
'dict' object has no attribute '%s'
" %key)
1011
def__setattr__
(self, key, value):
12 self[key] = value
編寫單元測試時,我們需要編寫乙個測試類,從unittest.testcase繼承。
以test開頭的方法就是測試方法,不以test開頭的方法不被認為是測試方法,測試的時候不會被執行。
對每一類測試都需要編寫乙個test_***()方法。由於unittest.testcase提供了很多內建的條件判斷,我們只需要呼叫這些方法就可以斷言輸出是否是我們所期望的。最常用的斷言就是assertequals():
1 self.assertequals(abs(-1), 1) #斷言函式返回的結果與1相等
另一種重要的斷言就是期待丟擲指定型別的error,比如通過d['empty']訪問不存在的key時,斷言會丟擲keyerror:
1with self.assertraises(keyerror):
2 value = d['
empty
']
而通過d.empty訪問不存在的key時,我們期待丟擲attributeerror:
1with self.assertraises(attributeerror):
2 value = d.empty
setup與teardown 可以在單元測試中編寫兩個特殊的setup()和teardown()方法。這兩個方法會分別在每呼叫乙個測試方法的前後分別被執行。
setup()和teardown()方法有什麼用呢?設想你的測試需要啟動乙個資料庫,這時,就可以在setup()方法中連線資料庫,在teardown()方法中關閉資料庫,這樣,不必在每個測試方法中重複相同的**:
1class
testdict(unittest.testcase):23
defsetup(self):
4print
'setup...'5
6def
teardown(self):
7print
'teardown...
'
可以再次執行測試看看每個測試方法呼叫前後是否會列印出setup...和teardown...。
1import
unittest
2from dict import
dict34
class
testdict(unittest.testcase):56
defsetup(self):
7print
'setup...'8
9def
teardown(self):
10print
'teardown...'11
12def
test_init(self):
13 d = dict(a=1, b='
test')
14 self.assertequals(d.a, 1)
15 self.assertequals(d.b, '
test')
16self.asserttrue(isinstance(d, dict))
1718
deftest_key(self):
19 d =dict()
20 d['
key'] = '
value
'21 self.assertequals(d.key, '
value')
2223
deftest_attr(self):
24 d =dict()
25 d.key = '
value
'26 self.asserttrue('
key'
ind)
27 self.assertequals(d['
key'], '
value')
2829
deftest_keyerror(self):
30 d =dict()
31with self.assertraises(keyerror):
32 value = d['
empty']
3334
deftest_attrerror(self):
35 d =dict()
36with self.assertraises(attributeerror):
37 value =d.empty
3839
if__name__ == '
__main__':
40 unittest.main()
單元測試可以有效地測試某個程式模組的行為,是未來重構**的信心保證。
單元測試的測試用例要覆蓋常用的輸入組合、邊界條件和異常。
單元測試**要非常簡單,如果測試**太複雜,那麼測試**本身就可能有bug。
單元測試通過了並不意味著程式就沒有bug了,但是不通過程式肯定有bug。
python unittest基礎用法
unittest 執行例項 基礎用法 import unittest 匯入unittest模組 defcalc a,b 被測的方法 return a b class testcale unittest.testcase 必須要整合unittest的testcase方法 deftest1 self r...
Python unittest學習筆記
python標準庫中的模組unittest提供了 測試工具。單元測試用於核實函式的某個方面沒問題 測試用例是一組單元測試,這些單元測試一起核實函式在各種情形下的行為都符合要求。良好的測試用例考慮到了函式可能收到的各種輸入,包含針對所有這些情形的測試。全覆蓋式測試用例包含一整套單元測試,涵蓋了各種可能...
python unittest 之mock學習筆記
mock的詳細用法 英文介紹 本文先對函式的mock方法進行演示。假設有檔案fun1和fun2,fun2中的函式呼叫了fun1中的函式。利用mock方法生成fun1中函式的乙個fake返回值,在此基礎上,對fun2中的函式進行單元測試。如下 fun1檔案 usr bin env python cod...