什么的單元測試 單元測試工具
測試是軟件開發的重要環節之一。按照軟件開發的過程測試可分為:單元測試、集成測試、系統測試、域測試(Field test)等。
單元測試(unit testing)在軟件開發領域有著悠久的歷史。在大多數有關單元測試的觀念中都有這么一個共同的理念,即它們由一組獨立的測試構成,其中每個測試針對一個單獨的軟件組件。在過程式程序設計的代碼中,“單元”一般來說指的就是函數,而在面向對象的代碼中則指的是類。
那么,我們究竟能否做到只測試系統中的某一個函數或類呢?在過程式系統中,通常是難以孤立地測試函數的,因為這種系統中的情況往往是頂層的函數調用其他函數,后者再調用另一些函數,最后直到機器層。而在面向對象的系統中,單獨測試類則要簡單一點,然而實際上類卻往往并不是“離群索居”的生物。想想看,在你寫過的所有類中有多少是沒有使用到別的類的?非常少這些極個別分子往往是那些小型的數據類或數據結構類,如棧和隊列(甚至就算是這樣的類也可能會用到其他類)。
測試的隔離性是單元測試的一個重要方面,然而為什么說它是重要的呢?畢竟,當整合軟件的各個部分時還可能出現許多錯誤。難道不應該是那些能夠覆蓋代碼中的廣泛功能區域的大型測試更為重要嗎?誠然,它們是重要的,我并不否認這一點,然而大型測試存在著一些問題:
q 錯誤定位:測試離被測試者越遠,就越難確定測試失敗究竟意味著什么。要想精確定位測試失敗的根源往往需要耗費大量的工作。你得檢查測試輸入、還要檢查失敗本身,然后還得確定這次失敗發生在從輸入到輸出的執行路徑上的哪一點。雖說對于單元測試來說這樣的工作也是免不了的,然而通常其工作量微乎其微。
q 執行時間:大型測試往往需要更長時間來運行。而這種長時耗性往往讓人無法忍受。需要太長時間運行的測試,結果往往是無法運行。
q 覆蓋:在大型測試中,往往難以看出某段代碼與用來測試它的值之間的聯系。我們通??梢酝ㄟ^覆蓋工具來查出某段代碼是否被一個測試覆蓋到了,但當添加新的代碼時,可能就需要花費可觀的工作量來創建檢驗這段新代碼的高層測試了。
而單元測試則做到了大型測試所不能做到的那些事情。利用單元測試可以獨立地對某一段代碼進行測試。我們可以將測試分組以便在某些特定條件下運行某些特定的測試,并在其他條件下運行另一些測試。我們還可以迅速定位錯誤。如果認為在某段代碼中存在著一個錯誤而且又可以在測試用具中使用這段代碼的話,我們通常能夠迅速地編寫出一段測試,看看我們所推測的錯誤是不是真的在那里。
測試的覆蓋種類
1.語句覆蓋:語句覆蓋就是設計若干個測試用例,運行被測試程序,使得每一條可執行語句至少執行一次。
2.判定覆蓋(也叫分支覆蓋):設計若干個測試用例,運行所測程序,使程序中每個判斷的取真分支和取假分支至少執行一次。
3.條件覆蓋:設計足夠的測試用例,運行所測程序,使程序中每個判斷的每個條件的每個可能取值至少執行一次。
4.判定——條件覆蓋:設計足夠的測試用例,運行所測程序,使程序中每個判斷的每個條件的每個可能取值至少執行一次,并且每個可能的判斷結果也至少執行一次。
5.條件組合測試:設計足夠的測試用例,運行所測程序,使程序中每個判斷的所有條件取值組合至少執行一次。
6.路徑測試:設計足夠的測試用例,運行所測程序,要覆蓋程序中所有可能的路徑。
用例的設計方案主要的有下面幾種:條件測試,基本路徑測試,循環測試。通過上面的方法可以實現測試用例對程序的邏輯覆蓋,和路徑覆蓋。
下面是好的單元測試所應具備的品質:
(1) 運行快;
(2) 能幫助我們定位問題所在。
在業界,人們在判斷某個特定的測試是否是單元測試這個問題上常常搖擺不定。如果一個測試中涉及了另外一個產品類,那它還能算是單元測試嗎?為了回答這個問題,我們回到剛才提到的兩點品質上來,即該測試運行起來快不快?它能幫我們快速定位錯誤嗎?比如有些測試較大,其中用到了好多類。那么實際上這種測試或許看上去像是小型的集成測試。就它們自身而言,可能運行起來比較快,然而要是你將它們一起運行呢?一個測試如果不僅測試了某個類還測試了與該類一起工作的幾個類,那么它往往會“越長越大”。如果你當時不花時間來使得一個類能夠在測試用具中單獨實例化的話,難道你還能指望當更多的代碼被添加進系統之后這件事會變得更容易嗎?永遠也不會。人們會不斷推諉,并且隨著時間的推移,原本短小的測試可能會變得需要十分之一秒才能執行完。