JUnit是一個開發源代碼的Java測試框架用於編寫和運行可重復的測試他是用於單元測試框架體系xUnit的一個實例(用於java語言)它包括以下特性
用於測試期望結果的斷言(Assertion)
用於共享共同測試數據的測試工具
用於方便的組織和運行測試的測試套件
圖形和文本的測試運行器
JUnit最初是由Erich Gamma(GoF之一)和Kent Beck(xp和refactor的先驅之一)編寫的
需要說明的是JUnit一般是用來進行單元測試的
因此需要了解被測試代碼的內部結構(即所謂的白盒測試)
另外junit是在xp編程和重構(refactor)中被極力推薦使用的工具
因為在實現自動單元測試的情況下可以大大的提高開發的效率
但是實際上編寫測試代碼也是需要耗費很多的時間和精力的
那麼使用這個東東好處到底在哪裡呢?筆者認為是這樣的
對於xp編程而言
要求在編寫代碼之前先寫測試
這樣可以強制你在寫代碼之前好好的思考代碼(方法)的功能和邏輯
否則編寫的代碼很不穩定
那麼你需要同時維護測試代碼和實際代碼
這個工作量就會大大增加
因此在xp編程中
基本過程是這樣的
構思-》編寫測試代碼-》編寫代碼-》測試
而且編寫測試和編寫代碼都是增量式的
寫一點測一點
在編寫以後的代碼中如果發現問題可以較塊的追蹤到問題的原因
減小回歸錯誤的糾錯難度
對於重構而言
其好處和xp編程中是類似的
因為重構也是要求改一點測一點
減少回歸錯誤造成的時間消耗
對於非以上兩種情況
我們在開發的時候使用junit寫一些適當的測試也是有必要的
因為一般我們也是需要編寫測試的代碼的
可能原來不是使用的junit
如果使用junit
而且針對接口(方法)編寫測試代碼會減少以後的維護工作
例如以後對方法內部的修改(這個就是相當於重構的工作了)
另外就是因為junit有斷言功能
如果測試結果不通過會告訴我們那個測試不通過
為什麼
而如果是想以前的一般做法是寫一些測試代碼看其輸出結果
然後再由自己來判斷結果使用正確
使用junit的好處就是這個結果是否正確的判斷是它來完成的
我們只需要看看它告訴我們結果是否正確就可以了
在一般情況下會大大提高效率
安裝JUnit
安裝很簡單
先到以下地址下載一個最新的zip包
下載完以後解壓縮到你喜歡的目錄下
假設是JUNIT_HOME
然後將JUNIT_HOME下的junit
jar包加到你的系統的CLASSPATH環境變量中
對於IDE環境
對於需要用到的junit的項目增加到lib中
其設置不同的IDE有不同的設置
這裡不多講
如何使用JUnit寫測試?
最簡單的范例如下
創建一個TestCase的子類
package junitfaq;
import java
util
*;
import junit
framework
*;
public class SimpleTest extends TestCase {
public SimpleTest(String name) {
super(name);
}
寫一個測試方法斷言期望的結果
public void testEmptyCollection() {
Collection collection = new ArrayList();
assertTrue(collectionisEmpty());
}
注意JUnit推薦的做法是以test作為待測試的方法的開頭這樣這些方法可以被自動找到並被測試
寫一個suite()方法它會使用反射動態的創建一個包含所有的testXxxx方法的測試套件
public static Test suite() {
return new TestSuite(SimpleTestclass);
}
寫一個main()方法以文本運行器的方式方便的運行測試
public static void main(String args[]) {
junittextuiTestRunnerrun(suite());
}
}
運行測試
以文本方式運行
java junitfaqSimpleTest
通過的測試結果是
Time:
OK (
tests)
Time上的小點表示測試個數
如果測試通過則顯示OK
否則在小點的後邊標上F
表示該測試失敗
每次的測試結果都應該是OK的
這樣才能說明測試是成功的
如果不成功就要馬上根據提示信息進行修正了
如果JUnit報告了測試沒有成功
它會區分失敗(failures)和錯誤(errors)
失敗是你的代碼中的assert方法失敗引起的
而錯誤則是代碼異常引起的
例如ArrayIndexOutOfBoundsException
以圖形方式運行
java junitswinguiTestRunner junitfaqSimpleTest
通過的測試結果在圖形界面的綠色條部分
以上是最簡單的測試樣例
在實際的測試中我們測試某個類的功能是常常需要執行一些共同的操作
完成以後需要銷毀所占用的資源(例如網絡連接
數據庫連接
關閉打開的文件等)
TestCase類給我們提供了setUp方法和tearDown方法
setUp方法的內容在測試你編寫的TestCase子類的每個testXxxx方法之前都會運行
而tearDown方法的內容在每個testXxxx方法結束以後都會執行
這個既共享了初始化代碼
又消除了各個測試代碼之間可能產生的相互影響
JUnit最佳實踐
Martin Fowler說過
當你試圖打印輸出一些信息或調試一個表達式時
寫一些測試代碼來替代那些傳統的方法
一開始
你會發現你總是要創建一些新的Fixture
而且測試似乎使你的編程速度慢了下來
然而不久之後
你會發現你重復使用相同的Fixture
而且新的測試通常只涉及添加一個新的測試方法
你可能會寫許多測試代碼
但你很快就會發現你設想出的測試只有一小部分是真正有用的
你所需要的測試是那些會失敗的測試
即那些你認為不會失敗的測試
或你認為應該失敗卻成功的測試
我們前面提到過測試是一個不會中斷的過程
一旦你有了一個測試
你就要一直確保其正常工作
以檢驗你所加入的新的工作代碼
不要每隔幾天或最後才運行測試
每天你都應該運行一下測試代碼
這種投資很小
但可以確保你得到可以信賴的工作代碼
你的返工率降低了
你會有更多的時間編寫工作代碼
不要認為壓力大
就不寫測試代碼
相反編寫測試代碼會使你的壓力逐漸減輕
應為通過編寫測試代碼
你對類的行為有了確切的認識
你會更快地編寫出有效率地工作代碼
下面是一些具體的編寫測試代碼的技巧或較好的實踐方法
不要用TestCase的構造函數初始化Fixture
而要用setUp()和tearDown()方法
不要依賴或假定測試運行的順序
因為JUnit利用Vector保存測試方法
所以不同的平台會按不同的順序從Vector中取出測試方法
避免編寫有副作用的TestCase
例如
如果隨後的測試依賴於某些特定的交易數據
就不要提交交易數據
簡單的會滾就可以了
當繼承一個測試類時
記得調用父類的setUp()和tearDown()方法
將測試代碼和工作代碼放在一起
一邊同步編譯和更新
(使用Ant中有支持junit的task
)
測試類和測試方法應該有一致的命名方案
如在工作類名前加上test從而形成測試類名
確保測試與時間無關
不要依賴使用過期的數據進行測試
導致在隨後的維護過程中很難重現測試
如果你編寫的軟件面向國際市場
編寫測試時要考慮國際化的因素
不要僅用母語的Locale進行測試
盡可能地利用JUnit提供地assert/fail方法以及異常處理的方法
可以使代碼更為簡潔
測試要盡可能地小
執行速度快
JUnit和ant結合
ant 提供了兩個 target
junit 和 junitreport 運行所有 測試用例
並生成 html 格式的報表
具體操作如下
將 junit
jar 放在 ANT_HOME\lib 目錄下
修改 buildxml 加入如下 內容
<property name=report value=report />
<target name=junitreport depends=clean compile>
<junit printsummary=on fork=true haltonfailure=false failureproperty=testsfailed showoutput=true>
<classpath refid=myclasspath/>
<formatter type=xml/>
<batchtest todir=${report}>
<fileset dir=${build}>
<include name=**/*Test*/>
</fileset>
</batchtest>
</junit>
<junitreport todir=${report}>
<fileset dir=${report}>
<include name=TEST*xml/>
</fileset>
<report format=frames todir=${report}/>
</junitreport>
<fail if=testsfailed> One or more tests failed check the report for detail </fail>
</target>
運行 這個 target
ant 會運行每個 TestCase
在 report 目錄下就有了 很多 TEST*
xml 和 一些網頁打開 report 目錄下的 l 就可以看到很直觀的測試運行報告
一目了然
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28784.html