文/柯采
單元測試是軟件測試中一種最基本的測試,能夠將每一個小的功能模塊、函數代碼進行高效率的測試,從而減少軟件后期代碼進行調試時出現大型BUG的出現率。單元測試能夠保證代碼的正確率,并且不會破壞這個功能模塊本體,做到一種驗證代碼正確性而不關心代碼具體實現細節,編寫單元測試能夠清楚的認識到代碼邏輯,讓程序員對自己的代碼質量有新的認識以及提供需求變更時修改該模塊的思路。在以前結構化編程方法中,普遍將每一個函數作為單元測試的主體,但自面向對象方法在軟件開發中的地位在計算機領域不斷深入,現在的單元測試主要將每一個類作為單元測試的主體,編寫好測試用例之后可直接測試每一個類中的所有方法,達到簡單高效的測試。單元測試是一種具有高效、驗證性、設計性的測試,在目前Java開發中具有廣泛的應用,且其中基于JUnit框架的Java單元測試最為成功。
JUnit是一種強大的開源的面向Java單元測試的框架,使用JUnit在Java各個開發過程中不斷進行單元測試將會大幅度提高程序質量,保證程序結果的正確運行。且JUnit可以幫助程序員進行自動測試,不需要編寫main方法造成main中大量的類接口出現,使得測試混亂。在JUnit中當你測試的功能模塊出現了錯誤,它都會提醒你是Failure或Error,這個好處是由于JUnit的斷言功能判斷你的代碼運行實際結果與期望值是否正確,提高了測試效率。
當繼承了TestCase類之后,就可以使用框架的單元測試功能。類里面的主要方法為setUp()和tearDown(),當開始在使用的過程中編程人員可以合理運用這兩種方法,其中setUp()主要寫測試前進行一些相關的配置以及變量的初始化操作,通常搭配注解@Before來使用,而tearDown()則主要寫測試之后一些連接的關閉比如數據庫連接以及必要的資源釋放操作,避免造成資源浪費,通常搭配注解@After來使用,并且這些方法都是自動編寫后自動進行調用。
想要驗證功能模塊是否達到預期的目標,就需要在編寫測試用例之后使用Assert類方法,其中包含了多種靜態斷言驗證方法。主要方法為AssertEquals():其中兩個參數分別為期望值和實際值,用來判斷是否相等;AssertTrue():用來判斷條件是否為真,參數類型為布爾型;AssertSame():參數類型為期望對象和實際對象,通過內存地址來判斷是否相等。之所以繼承TestCase類就能夠寫單元測試是因為TestCase類繼承了Assert類擁有了用于驗證的斷言功能。當測試后報Failure時是因為斷言失敗,檢查到與預期不符,報Error時是代碼本身存在隱患,為代碼邏輯問題。
當每一個測試方法寫好之后,必須搭配@Test注解來修飾讓JUnit知道這是測試方法,并且作為測試方法的函數名也必須為publicvoid無參函數進行修飾,同時在寫測試方法之前,需要為測試方法創建一個源代碼目錄,并且在這個目錄下創建的包名必須與被測試類的包名相同。在測試方法中需要進行獨立的測試,不能與其他方法有關聯。用一個簡單的測試類框架例子來說明,如下:

其中測試類名一般為XxxTest類,測試方法也盡量使用testxxx()來表明測試的是哪一個方法,這樣看起來直觀簡潔,容易找到出現BUG的方法塊。
下面通過判斷一個具有年份是否為閏年方法的類(Year)來編寫測試用例和測試用例類(YearTest),用JUnit來進行簡單的測試。
下面為被測試類代碼:
下面為測試類的單元測試代碼:


運行上面四個測試方法按照被測試方法的功能描述都會出現正確的驗證,第一個測試方法主要是看設定的年份為2000年,是否與預期的相等;第二個方法判斷2000年是否為閏年;第三個方法超出大于等于0的下限,使用負數來測試是否正確;第四個方法通過下界為0來測試邊界值0是否位閏年,但只要JUnit出現某一個方法為Faliure就說明哪一個方法中出現了沒有預料到的BUG,與預期發生了違背的現象,就能夠及時讓程序員將BUG修改過來,以免后期進行運行時出現嚴重的錯誤,軟件的質量才得以保證。
JUnit的強大之處在于能夠自動對測試方法進行測試且能夠進行驗證性的判斷,大大改善了使用main函數進行測試的復雜程度,更多的程序員也樂意使用JUnit進行方便高效的單元測試,對提高軟件生命周期和質量有著促進作用,同時也節省了軟件的修復時間,減少了延遲發布的概率。在JUnit4出現之后,擴充了更多的新功能,不僅有著開源的優勢,還能以JUnit為基礎的Cactus擴充為服務器上的Java應用進行測試。目前由于軟件測試在軟件生命周期中占重要位置,所以以JUnit框架進行的Java單元測試也有著廣闊的市場前景。