1、相關概念
Ø JUnit:是一個開發源代碼的Java測試框架,用於編寫和運行可重復的測試。它是用於單元測試框架體系xUnit的一個實例(用於java語言)。主要用於白盒測試,回歸測試。
Ø 白盒測試:把測試對象看作一個打開的盒子,程序內部的邏輯結構和其他信息對測試人
員是公開的。
Ø 回歸測試:軟件或環境的修復或更正後的再測試,自動測試工具對這類測試尤其有用。
Ø 單元測試:最小粒度的測試,以測試某個功能或代碼塊。一般由程序員來做,因為它需要知道內部程序設計和編碼的細節。
2、 單元測試
2.1、單元測試的好處
Ø 提高開發速度,測試是以自動化方式執行的,提升了測試代碼的執行效率。
Ø 提高軟件代碼質量,它使用小版本發布至集成,便於實現人員除錯。同時引入重構概念,讓代碼更干淨和富有彈性。
Ø 提升系統的可信賴度,它是回歸測試的一種。支持修復或更正後的“再測試”,可確保代碼的正確性。
2.2、單元測試的針對對象
Ø 面向過程的軟件開發針對過程。
Ø 面向對象的軟件開發針對對象。
Ø 可以做類測試,功能測試,接口測試(最常用於測試類中的方法)。
2.3、單元測試工具和框架
目前的最流行的單元測試工具是xUnit系列框架,常用的根據語言不同分為JUnit(java),CppUnit(C++),DUnit (Delphi ),NUnit(.net),PhpUnit(Php )等等。
單元測試框架的第一個和最傑出的應用就是由Erich Gamma (《設計模式》的作者)和Kent Beck(XP(Extreme Programming)的創始人 )提供的開放源代碼的JUnit。
3、Junit入門簡介
3.1、JUnit的好處和JUnit測試編寫原則
使用JUnit的好處:
Ø 可以使測試代碼與產品代碼分開。
Ø 針對某一個類的測試代碼通過較少的改動便可以應用於另一個類的測試。
Ø 易於集成到測試人員的構建過程中,JUnit和Ant的結合可以實施增量開發。
Ø JUnit是公開源代碼的,可以進行二次開發。
Ø 可以方便地對JUnit進行擴展。
JUnit測試編寫原則:
Ø 簡化測試的編寫,這種簡化包括測試框架的學習和實際測試單元的編寫。
Ø 使測試單元保持持久性。
Ø 可以利用既有的測試來編寫相關的測試。
3.2、JUnit的特征
Ø 使用斷言方法判斷期望值和實際值差異,返回Boolean值。
Ø 測試驅動設備使用共同的初始化變量或者實例。
Ø 測試包結構便於組織和集成運行。
Ø 支持圖型交互模式和文本交互模式。
3.3 JUnit框架組成
Ø 對測試目標進行測試的方法與過程集合,可稱為測試用例(TestCase)。
Ø 測試用例的集合,可容納多個測試用例(TestCase),將其稱作測試包(TestSuite)。
Ø 測試結果的描述與記錄。(TestResult) 。
Ø 測試過程中的事件監聽者(TestListener)。
Ø 每一個測試方法所發生的與預期不一致狀況的描述,稱其測試失敗元素(TestFailure)
Ø JUnit Framework中的出錯異常(AssertionFailedError)。
JUnit框架是一個典型的Composite模式:TestSuite可以容納任何派生自Test的對象;當調用TestSuite對象的run()方法是,會遍歷自己容納的對象,逐個調用它們的run()方法。
3.5 JUnit中常用的接口和類
Ø Test接口:運行測試和收集測試結果
Test接口使用了Composite設計模式,是單獨測試用例(TestCase),聚合測試模式(TestSuite)及測試擴展(TestDecorator)的共同接口。 它的public int countTestCases()方法,用來統計測試時有多少個TestCase。另外一個方法就是public void run( TestResult ),TestResult是實例接受測試結果, run方法執行本次測試。
Ø TestCase抽象類:定義測試中固定方法
TestCase是Test接口的抽象實現,(不能被實例化,只能被繼承)其構造函數TestCase(string name)根據輸入的測試名稱name創建一個測試實例。由於每一個TestCase在創建時都要有一個名稱,若測試失敗了,便可識別出是哪個測試失敗。
TestCase類中包含的setUp()、tearDown()方法。
setUp()方法集中初始化測試所需的所有變量和實例,並且在依次調用測試類中的每個測試方法之前再次執行setUp()方法。
tearDown()方法則是在每個測試方法之後,釋放測試程序方法中引用的變量和實例。
開發人員編寫測試用例時,只需繼承TestCase,來完成run方法即可,然後JUnit獲得測試用例,執行它的run方法,把測試結果記錄在TestResult之中。
Ø Assert靜態類:一系列斷言方法的集合
Assert包含了一組靜態的測試方法,用於期望值和實際值比對是否正確,即測試失敗,Assert類就會拋出一AssertionFailedError異常,JUnit測試框架將這種錯誤歸入Failes並加以記錄,同時標志為未通過測試。如果該類方法中指定一個String類型的傳參則該參數將被做為AssertionFailedError異常的標識信息,告訴測試人員改異常的詳細信息。
JUnit 提供了6大類31組斷言方法,包括基礎斷言、數字斷言、字符斷言、布爾斷言、對象斷言。其中assertEquals(Object expcted,Object actual)內部邏輯判斷使用equals()方法,這表明斷言兩個實例的內部哈希值是否相等時,最好使用該方法對相應類實例的值進行比較。
而assertSame(Object expected,Object actual)內部邏輯判斷使用了Java運算符“==”,這表明該斷言判斷兩個實例是否來自於同一個引用(Reference),最好使用該方法對不同類的實例的值進行比對。
asserEquals(String message,String expected,String actual)該方法對兩個字符串進行邏輯比對,如果不匹配則顯示著兩個字符串有差異的地方。
ComparisonFailure類提供兩個字符串的比對,不匹配則給出詳細的差異字符。
Ø TestSuite測試包類??多個測試的組合
TestSuite類負責組裝多個Test Cases。待測得類中可能包括了對被測類的多個測試,而TestSuit負責收集這些測試,使我們可以在一個測試中,完成全部的對被測類的多個測試。TestSuite類實現了Test接口,且可以包含其它的TestSuites。它可以處理加入Test時的所有拋出的異常。
TestSuite處理測試用例有6個規約(否則會被拒絕執行測試)
² 測試用例必須是公有類(Public)
² 用例必須繼承與TestCase類
² 測試用例的測試方法必須是公有的( Public )
² 測試用例的測試方法必須被聲明為Void
² 測試用例中測試方法的前置名詞必須是test
² 測試用例中測試方法誤任何傳遞參數
Ø TestResult結果類和其它類與接口
TestResult結果類集合了任意測試累加結果,通過TestResult實例傳遞個每個測試的Run()方法。TestResult在執行TestCase是如果失敗會異常拋出。
TestListener接口是個事件監聽規約,可供TestRunner類使用。它通知listener的對象相關事件,方法包括測試開始startTest(Test test),測試結束endTest(Test test),錯誤,增加異常addError(Test test,Throwable t)和增加失敗addFailure(Test test,AssertionFailedError t)。
TestFailure失敗類是個“失敗”狀況的收集類,解釋每次測試執行過程中出現的異常情況。其toString()方法返回“失敗”狀況的簡要描述
4、Eclipse中JUnit的使用
測試對於保證軟件開發質量有著非常重要的作用,單元測試更是必不可少,JUnit是一個非常強大的單元測試包,可以對一個/多個類的單個/多個方法測試,還可以將不同的TestCase組合成TestSuit,使測試任務自動化。
Eclipse同樣集成了JUnit,可以非常方便地編寫TestCase。Eclipse自帶了一個JUnit的插件,不用安裝就可以在你的項目中開始測試相關的類,並且可以調試你的測試用例和被測試類。
4.1、Eclipse中JUint使用步驟
以下步驟環境為Eclipse SDK 3.2.2及JUnit3.8.1
Ø 新建一個測試用例或選擇已有的所想測試的JAVA文件,點擊“File->New->…”菜單項或右擊文件,在彈出的“New”對話框中選擇“JUnit Test Case”,就進入“New JUnit Test Case”對話框
Ø 在“New JUnit TestCase”對話框填寫相應的欄目,主要有Name(測試用例名),SuperClass(若JUnit的版本是3.8.1,則測試的超類一般默認為junit.framework.TestCase; 若JUnit版本是JUnit 4.4,則默認超類為java.lang.Object。),Class Under Test(被測試的類),Source Folder(測試用例保存的目錄),Package(測試用例包名),及是否自動生成main,setUp,tearDown方法。在此一般填寫NAME及選上復選上setUpt和teardown即可。
Ø 點擊“Next>”按鈕,則進入Test Methods,在此你可以直接勾選你想測試的被測試類的方法,Eclipse將自動生成與被選方法相應的測試方法,點擊“Fishish”按鈕後一個測試用例就創建好了。
Ø 編寫完成測試用例後,點擊“Run”按鈕就可以看到運行結果了。
補充:要使用JUnit,您必須首先將JUnit JAR保存在項目的Build路徑上並創建一個測試類。將JUnit保存在項目的Build路徑上的步驟為:
右擊項目—>選擇菜單底部的Properties選擇Java Build Path—>選擇Libraries—>點擊Add Variable按鈕—>查看已有的列表中有無JUnit文件,若沒有,則點擊Configure Variable—>New按鈕,輸入JUNIT_LIB作為變量名稱,編輯該變量並指向解壓後的JUnit目錄中的一個名為JUnit.jar的文件—>然後在選擇剛才添加的jar文件依次點擊OK即可。
4.2、Eclipse中JUnit應用示例
下面我們作一個在Eclipse中利用JUnit對HelloWorld的測試 測試方法:
Ø HelloWorld.sayHello()是否執行正常,並且結果也符合要求
Ø HelloWorld.add()方法是否與我們預期一樣執行
下一步,我們准備對這兩個方法進行測試,確保功能正常。選中HelloWorld.java,右鍵點擊,選擇New->JUnit Test Case:
進入下面這個頁面,在此諸多欄目已經填好,即是這個需要測試的文件的相關信息,若是想在測試完之後即刪除測試文件,也可更改路徑。(本機在Eclipse已有的JUnit3.8.1的基礎上又添加了一個新版本JUnit4.4)
點擊Next進入Test Methods,在此選擇所要測試的方法sayHello及add。
點擊Finish,最後編寫完成測試用例代碼如下:
直接運行Run->Run As->JUnit Test,就可以看到JUnit測試結果:
綠色表示測試通過,只要有1個測試未通過,就會顯示紅色並列出未通過測試的方法。
5、後記
從上面的來看,JUnit的使用並不很難,但關鍵就是最後一步完成測試碼,即編寫TestCase。要編寫一個好的TestCase卻並非易事。一個不好的TestCase往往是既浪費了時間,也起不了實際的作用。相反,一個好的TestCase,不僅可以很好的指出代碼中存在的問題,而且也可以作為代碼更准確的文檔,同時還在持續集成的過程中起非常重要的作用。我們在作測試寫TestCase時需要注意的幾點:
Ø 測試的獨立性:一次只測試一個對象,方便定位出錯的位置。這有兩層意思:一個TestCase,只測試一個對象;一個TestMethod,只測試這個對象中的一個方法。
Ø 給測試方法一個合適的名字。 一般取名為原來的方法名後加一個Test。
Ø 在assert函數中給出失敗的原因,如:assertTrue( “… should be true”, ……),方便查錯。在這個例子中,如果無法通過assertTrue,那麼給出的消息將被顯示。在junit中每個assert函數都有第一個參數是出錯時顯示消息的函數原型。
Ø 測試所有可能引起失敗的地方,如:一個類中頻繁改動的函數。對於那些僅僅只含有getter/setter的類,如果是由IDE(如Eclipse)產生的,則可不測;如果是人工寫,那麼最好測試一下。
Ø 在setUp和tearDown中的代碼不應該是與測試方法相關的,而應該是全局相關的。如針對與測試方法A和B,在setUp和tearDown中的代碼應該是A和B都需要的代碼。
Ø 測試代碼的組織:相同的包,不同的目錄。這樣,測試代碼可以訪問被測試類的protected變量/方法,方便測試代碼的編寫。放在不同的目錄,則方便了測試代碼的管理以及代碼的打包和發布。