單元測試是用於檢查模塊、函數或類的正確性的測試工作。
例如,對於函數abs(),我們可以編寫以下測試用例:
輸入正數,如1、1.2、0.99,並期望返回值與輸入相同;
輸入負數,如-1、-1.2、-0.99,希望返回值與輸入相反;
輸入0,期望返回0;
輸入非數字類型,如None、【】、{},期望引發TypeError。
將上述測試用例放入測試模塊是壹個完整的單元測試。
如果單元測試通過,意味著我們測試的功能可以正常工作。如果單元測試失敗,要麽是函數中存在bug,要麽是測試條件輸入不正確。簡而言之,需要修復它才能通過單元測試。
通過單元測試有什麽意義?如果我們修改abs()函數的代碼,我們只需要再次運行單元測試。如果通過,意味著我們的修改不會影響abs()函數的原始行為。如果失敗,則意味著我們的修改與原始行為不壹致。要麽修改代碼,要麽修改測試。
這種測試驅動開發模型的最大優勢是確保程序模塊的行為符合我們設計的測試用例。當將來修改它時,它可以極大地確保模塊的行為仍然正確。
讓我們寫壹個Dict類。該類的行為與dict壹致,但可以通過屬性訪問。它的用法如下:
& gt& gt& gtd = Dict(a = 1,b=2)
& gt& gt& gtd【a】
1
& gt& gt& gt地方檢察官
1
Mydict.py代碼如下:
類別字典(字典):
def _ _ init _ _(self,**kw):
超級(Dict,self)。_ _ init _ _(*千瓦)
def _ _ getattr _ _(self,key):
嘗試:
歸還自己【鑰匙】
除了密鑰錯誤:
引發attribute error(r““Dict“對象沒有屬性“% s““% key)
def _ _ setattr _ _(self,key,value):
self【key】=值
為了編寫單元測試,我們需要引入Python附帶的unittest模塊,並編寫如下mydict_test.py:
導入單元測試
從我的字典導入字典
類TestDict(unittest。測試案例):
def test_init(自身):
d = Dict(a = 1,b =‘test’)
self . assert equals(d . a,1)
自我斷言等(d.b,“測試”)
self . assert true(is instance(d,dict))
定義測試鍵(自身):
d =字典()
d【‘key‘】=‘value‘
self . assert equals(d . key,value)
定義測試屬性(自身):
d =字典()
d . key =‘值‘
self . assert true(d中的“key”)
self . assert equals(d【‘key‘】,value)
def test _ key error(self):
d =字典()
with self . assert raises(key error):
value = d【‘empty‘】
def test _ atterror(self):
d =字典()
with self . assert raises(attribute error):
值= d.empty
在編寫單元測試時,我們需要編寫壹個繼承自unittest.TestCase的測試類。
以test開始的方法是測試方法。不以test開頭的方法不被視為測試方法,並且不會在測試期間執行。
您需要為每種類型的測試編寫壹個test_xxx()方法。因為單元測試。TestCase提供了許多內置的條件判斷,我們只需要調用這些方法來斷言輸出是否是我們所期望的。最常用的斷言是assertEquals():
自我。assert equals(ABS(-1),1)#斷言函數返回與1相同的結果。
另壹個重要的斷言是預期拋出特定類型的錯誤。例如,當通過d【‘empty‘】訪問壹個不存在的鍵時,斷言將拋出壹個KeyError:
with self . assert raises(key error):
value = d【‘empty‘】
當通過d.empty訪問壹個不存在的鍵時,我們期望拋出壹個AttributeError:
with self . assert raises(attribute error):
值= d.empty
運行單元測試
壹旦編寫了單元測試,我們就可以運行它了。運行它的最簡單方法是在mydict_test.py的末尾添加兩行代碼:
if _ _ name _ _ = =‘_ _ main _ _‘:
unittest.main()
這允許您將mydict_test.py作為普通python腳本運行:
$ python mydict_test.py
另壹種更常用的方法是直接在命令行上用參數-m unittest運行單元測試:
$ python -m unittest mydict_test
.....
-
在0.000秒內運行5次測試
好
建議這樣做,因為它可以壹次批量運行許多單元測試,並且有許多工具可以自動運行這些單元測試。
安裝和拆卸
您可以在單元測試中編寫兩個特殊的setUp()和tearDown()方法。這兩個方法將在調用每個測試方法之前和之後執行。
setUp()和tearDown()方法有什麽用?假設您的測試需要啟動壹個數據庫。此時,您可以在setUp()方法中連接數據庫並在tearDown()方法中關閉數據庫,這樣就不必在每個測試方法中重復相同的代碼:
類TestDict(unittest。測試案例):
定義設置(自身):
打印“設置。。。”
定義拆卸(自身):
打印“拆卸。。。”
您可以再次運行測試以查看安裝程序是否...和拆卸...將在每次測試方法調用前後打印。
總結
單元測試可以有效地測試程序模塊的行為,這是未來重構代碼的信心保證。
單元測試的測試用例應該涵蓋常見的輸入組合、邊界條件和異常。
單元測試代碼應該非常簡單。如果測試代碼過於復雜,測試代碼本身可能存在bug。
通過單元測試並不意味著程序中沒有bug,但如果您沒有通過程序,則壹定會有bug。