單元測試應該測試什麼?——Right-BICEP
Right——結果是否正確?
B——是否所有的邊界條件都是正確的?
I——能查一下反響關聯嗎?
C——能用其它手段交叉檢查一下嗎?
E——你是否可以強制錯誤條件發生?
P——是否滿足性能要求?
結果是否正確
這 個最簡單不過了,就是看程序運行之後的結構和文檔是否一致。當然可能很多的時候一個方法沒有很完整的文檔描述它,那至少也應該有簡單的文字描述,否則沒有 判斷是否正確的依據了。一個原則是:對於驗證被測方法是否正確的這件事情,如果某些做法能夠使它變得更加容易,那麼就採納它吧。
邊界條件CORRECT
很多臭蟲都會集中在邊界附近,所以應該多注意。
一致性(Conformance)——值是否符合預期的格式?
很多時候,傳遞給方法的值或者方法運行後產生的值必須符合某種特定的格式。必須考慮的是,如果數據不能像期望的那樣符合格式要求,將會出現什麼情況。
有序性(Ordering)——一組值是該有序的,還是該無序的?
應該考慮數據順序,或者是在一個很大的數據集合中某一數據的位置。
區間性(Range)——值是否在一個合理的最大值和最小值的範圍之內?
對於一個變量,它所屬類型的取值範圍可能比需要的或想要的更加寬廣。比如,人的年齡、角度等。
引用、耦合性(Reference)——代碼是否引用了一些不受代碼本身直接控制的外部因素?
如果對於類的狀態、其它對象的狀態,或者全局應用程序的狀態,需要作一些假設,那麼就需要對代碼進行測試,保證其在假設未滿足的情況下運行良好。前置條件和後置條件都必須檢測。
前置條件(preconditions):系統必須處於什麼狀態下,該方法才能運行。當前置條件不能滿足的情況下程序是否能夠正確運行。
後置條件(postconditions):方法運行之後將會有哪些狀態發生。程序的返回結構必須檢查,伴隨產生的副作用也必須檢查。
存在性(Existence)——值是否存在(要小心null、0、“”、有時可能還需要注意空格字符串)?
存在性的問題很容易出現在方法的參數上,也經常出現在方法要用到的類的屬性上。特別是引用類型,要特別注意。當遇到null等值時,採取什麼策略需要及早考慮。應該形成一貫的處理策略,形成風格。可以考慮拋出異常,並且Message描述問題應儘量細緻明確。
基數性(Cardinality)——是否恰好有足夠的值?
對基數性問題的認識我目前還不是很透徹。
時間性,絕對的或者相當的(Time)——所有事情是否都是按順序發生的?是否在正確的時間?是否及時?
測試邊界是最有價值的工作,因爲bug通常會集中在這裏。邊界測試需要考慮的主要問題:
完全僞造或者不一致的輸入數據。
格式錯誤的數據。
空值或者不完整的值,如0, 0.0, “”, null之類的。
一些與意料中的合理值相去甚遠的數值。
如果是傳入一系列數據,要考慮是否允許重複,考慮值是否應該有特定順序,順序是否可能有錯誤等。
檢查反向關聯
對於一些方法,我們可以使用反向的邏輯關係來驗證它們。要注意的是,當你同時編寫了原方法和它的方向測試時,一些bug可能會被在兩個函數中都出現的錯誤所掩蓋。在可能的情況下,應該使用不同的原理來編寫反向測試。
使用其他手段來實現交叉檢查
通常解決一個問題會有多種手段,如果你選擇了其中一個方法,那麼就可以用其它的方法來檢驗它。另一種方法就是:使用類本身不同組成部分的數據,並且確信它們能“合起來”。
強制產生錯誤條件
應當能夠通過強制引發錯誤,來測試你的代碼是如何處理所有這些真實世界中的問題的。
下面是一些我們能想到的環境方面的因素:
內存耗光
磁盤用滿
時鐘出問題
網絡不可用或者有問題
系統過載
受限的調色板
顯示分辨率過高或者過低
性能特性
一個檢查起來會很有益處的部分是性能特性,而不是性能本身。