JUnit是一個(gè)開(kāi)發(fā)源代碼的Java測(cè)試框架,用于編寫(xiě)和運(yùn)行可重復(fù)的測(cè)試。他是用于單元測(cè)試框架體系xUnit的一個(gè)實(shí)例(用于java語(yǔ)言)。它包括以下特性:
1、用于測(cè)試期望結(jié)果的斷言(Assertion)
2、用于共享共同測(cè)試數(shù)據(jù)的測(cè)試工具
3、用于方便的組織和運(yùn)行測(cè)試的測(cè)試套件
4、圖形和文本的測(cè)試運(yùn)行器
JUnit最初是由Erich Gamma(GoF之一)和Kent Beck(xp和refactor的先驅(qū)之一)編寫(xiě)的.
需要說(shuō)明的是junit一般是用來(lái)進(jìn)行單元測(cè)試的,因此需要了解被測(cè)試代碼的內(nèi)部結(jié)構(gòu)(即所謂的白盒測(cè)試),另外junit是在xp編程和重構(gòu)(refactor)中被極力推薦使用的工具,因?yàn)樵趯?shí)現(xiàn)自動(dòng)單元測(cè)試的情況下可以大大的提高開(kāi)發(fā)的效率,但是實(shí)際上編寫(xiě)測(cè)試代碼也是需要耗費(fèi)很多的時(shí)間和精力的,那么使用這個(gè)東東好處到底在哪里呢?筆者認(rèn)為是這樣的:
1、對(duì)于xp編程而言,要求在編寫(xiě)代碼之前先寫(xiě)測(cè)試,這樣可以強(qiáng)制你在寫(xiě)代碼之前好好的思考代碼(方法)的功能和邏輯,否則編寫(xiě)的代碼很不穩(wěn)定,那么你需要同時(shí)維護(hù)測(cè)試代碼和實(shí)際代碼,這個(gè)工作量就會(huì)大大增加。因此在xp編程中,基本過(guò)程是這樣的:構(gòu)思-》編寫(xiě)測(cè)試代碼-》編寫(xiě)代碼-》測(cè)試,而且編寫(xiě)測(cè)試和編寫(xiě)代碼都是增量式的,寫(xiě)一點(diǎn)測(cè)一點(diǎn),在編寫(xiě)以后的代碼中如果發(fā)現(xiàn)問(wèn)題可以較塊的追蹤到問(wèn)題的原因,減小回歸錯(cuò)誤的糾錯(cuò)難度
2、對(duì)于重構(gòu)而言,其好處和xp編程中是類(lèi)似的,因?yàn)橹貥?gòu)也是要求改一點(diǎn)測(cè)一點(diǎn),減少回歸錯(cuò)誤造成的時(shí)間消耗。
3、對(duì)于非以上兩種情況,我們?cè)陂_(kāi)發(fā)的時(shí)候使用junit寫(xiě)一些適當(dāng)?shù)臏y(cè)試也是有必要的,因?yàn)橐话阄覀円彩切枰帉?xiě)測(cè)試的代碼的,可能原來(lái)不是使用的junit,如果使用junit,而且針對(duì)接口(方法)編寫(xiě)測(cè)試代碼會(huì)減少以后的維護(hù)工作,例如以后對(duì)方法內(nèi)部的修改(這個(gè)就是相當(dāng)于重構(gòu)的工作了)。另外就是因?yàn)閖unit有斷言功能,如果測(cè)試結(jié)果不通過(guò)會(huì)告訴我們那個(gè)測(cè)試不通過(guò),為什么,而如果是想以前的一般做法是寫(xiě)一些測(cè)試代碼看其輸出結(jié)果,然后再由自己來(lái)判斷結(jié)果使用正確,使用junit的好處就是這個(gè)結(jié)果是否正確的判斷是它來(lái)完成的,我們只需要看看它告訴我們結(jié)果是否正確就可以了,在一般情況下會(huì)大大提高效率。
JUnit入門(mén)
cherami 整理
安裝JUnit
安裝很簡(jiǎn)單,先到以下地址下載一個(gè)最新的zip包:
http://download.sourceforge.net/junit/
下載完以后解壓縮到你喜歡的目錄下,假設(shè)是JUNIT_HOME,然后將JUNIT_HOME下的junit.jar包加到你的系統(tǒng)的CLASSPATH環(huán)境變量中,對(duì)于IDE環(huán)境,對(duì)于需要用到的junit的項(xiàng)目增加到lib中,其設(shè)置不同的IDE有不同的設(shè)置,這里不多講。
如何使用JUnit寫(xiě)測(cè)試?
最簡(jiǎn)單的范例如下:
1、創(chuàng)建一個(gè)TestCase的子類(lèi):
package junitfaq;
import java.util.*;
import junit.framework.*;
public class SimpleTest extends TestCase {
public SimpleTest(String name) {
super(name);
}
2、寫(xiě)一個(gè)測(cè)試方法斷言期望的結(jié)果:
public void testEmptyCollection() {
Collection collection = new ArrayList();
assertTrue(collection.isEmpty());
}
注意:JUnit推薦的做法是以test作為待測(cè)試的方法的開(kāi)頭,這樣這些方法可以被自動(dòng)找到并被測(cè)試。
3、寫(xiě)一個(gè)suite()方法,它會(huì)使用反射動(dòng)態(tài)的創(chuàng)建一個(gè)包含所有的testXxxx方法的測(cè)試套件:
public static Test suite() {
return new TestSuite(SimpleTest.class);
}
4、寫(xiě)一個(gè)main()方法以文本運(yùn)行器的方式方便的運(yùn)行測(cè)試:
public static void main(String args[]) {
junit.textui.TestRunner.run(suite());
}
}
5、運(yùn)行測(cè)試:
以文本方式運(yùn)行:
java junitfaq.SimpleTest
通過(guò)的測(cè)試結(jié)果是:
.
Time: 0
OK (1 tests)
Time上的小點(diǎn)表示測(cè)試個(gè)數(shù),如果測(cè)試通過(guò)則顯示OK。否則在小點(diǎn)的后邊標(biāo)上F,表示該測(cè)試失敗。
每次的測(cè)試結(jié)果都應(yīng)該是OK的,這樣才能說(shuō)明測(cè)試是成功的,如果不成功就要馬上根據(jù)提示信息進(jìn)行修正了。
如果JUnit報(bào)告了測(cè)試沒(méi)有成功,它會(huì)區(qū)分失敗(failures)和錯(cuò)誤(errors)。失敗是你的代碼中的assert方法失敗引起的;而錯(cuò)誤則是代碼異常引起的,例如ArrayIndexOutOfBoundsException。
以圖形方式運(yùn)行:
java junit.swingui.TestRunner junitfaq.SimpleTest
通過(guò)的測(cè)試結(jié)果在圖形界面的綠色條部分。
以上是最簡(jiǎn)單的測(cè)試樣例,在實(shí)際的測(cè)試中我們測(cè)試某個(gè)類(lèi)的功能是常常需要執(zhí)行一些共同的操作,完成以后需要銷(xiāo)毀所占用的資源(例如網(wǎng)絡(luò)連接、數(shù)據(jù)庫(kù)連接,關(guān)閉打開(kāi)的文件等),TestCase類(lèi)給我們提供了setUp方法和tearDown方法,setUp方法的內(nèi)容在測(cè)試你編寫(xiě)的TestCase子類(lèi)的每個(gè)testXxxx方法之前都會(huì)運(yùn)行,而tearDown方法的內(nèi)容在每個(gè)testXxxx方法結(jié)束以后都會(huì)執(zhí)行。這個(gè)既共享了初始化代碼,又消除了各個(gè)測(cè)試代碼之間可能產(chǎn)生的相互影響。
JUnit最佳實(shí)踐
Martin Fowler說(shuō)過(guò):“當(dāng)你試圖打印輸出一些信息或調(diào)試一個(gè)表達(dá)式時(shí),寫(xiě)一些測(cè)試代碼來(lái)替代那些傳統(tǒng)的方法。”一開(kāi)始,你會(huì)發(fā)現(xiàn)你總是要?jiǎng)?chuàng)建一些新的Fixture,而且測(cè)試似乎使你的編程速度慢了下來(lái)。然而不久之后,你會(huì)發(fā)現(xiàn)你重復(fù)使用相同的Fixture,而且新的測(cè)試通常只涉及添加一個(gè)新的測(cè)試方法。
你可能會(huì)寫(xiě)許多測(cè)試代碼,但你很快就會(huì)發(fā)現(xiàn)你設(shè)想出的測(cè)試只有一小部分是真正有用的。你所需要的測(cè)試是那些會(huì)失敗的測(cè)試,即那些你認(rèn)為不會(huì)失敗的測(cè)試,或你認(rèn)為應(yīng)該失敗卻成功的測(cè)試。
我們前面提到過(guò)測(cè)試是一個(gè)不會(huì)中斷的過(guò)程。一旦你有了一個(gè)測(cè)試,你就要一直確保其正常工作,以檢驗(yàn)?zāi)闼尤氲男碌墓ぷ鞔a。不要每隔幾天或最后才運(yùn)行測(cè)試,每天你都應(yīng)該運(yùn)行一下測(cè)試代碼。這種投資很小,但可以確保你得到可以信賴(lài)的工作代碼。你的返工率降低了,你會(huì)有更多的時(shí)間編寫(xiě)工作代碼。
不要認(rèn)為壓力大,就不寫(xiě)測(cè)試代碼。相反編寫(xiě)測(cè)試代碼會(huì)使你的壓力逐漸減輕,應(yīng)為通過(guò)編寫(xiě)測(cè)試代碼,你對(duì)類(lèi)的行為有了確切的認(rèn)識(shí)。你會(huì)更快地編寫(xiě)出有效率地工作代碼。
下面是一些具體的編寫(xiě)測(cè)試代碼的技巧或較好的實(shí)踐方法:
1. 不要用TestCase的構(gòu)造函數(shù)初始化Fixture,而要用setUp()和tearDown()方法。
2. 不要依賴(lài)或假定測(cè)試運(yùn)行的順序,因?yàn)镴Unit利用Vector保存測(cè)試方法。所以不同的平臺(tái)會(huì)按不同的順序從Vector中取出測(cè)試方法。
3. 避免編寫(xiě)有副作用的TestCase。例如:如果隨后的測(cè)試依賴(lài)于某些特定的交易數(shù)據(jù),就不要提交交易數(shù)據(jù)。簡(jiǎn)單的會(huì)滾就可以了。
4. 當(dāng)繼承一個(gè)測(cè)試類(lèi)時(shí),記得調(diào)用父類(lèi)的setUp()和tearDown()方法。
5. 將測(cè)試代碼和工作代碼放在一起,一邊同步編譯和更新。(使用Ant中有支持junit的task.)
6. 測(cè)試類(lèi)和測(cè)試方法應(yīng)該有一致的命名方案。如在工作類(lèi)名前加上test從而形成測(cè)試類(lèi)名。
7. 確保測(cè)試與時(shí)間無(wú)關(guān),不要依賴(lài)使用過(guò)期的數(shù)據(jù)進(jìn)行測(cè)試。導(dǎo)致在隨后的維護(hù)過(guò)程中很難重現(xiàn)測(cè)試。
8. 如果你編寫(xiě)的軟件面向國(guó)際市場(chǎng),編寫(xiě)測(cè)試時(shí)要考慮國(guó)際化的因素。不要僅用母語(yǔ)的Locale進(jìn)行測(cè)試。
9. 盡可能地利用JUnit提供地assert/fail方法以及異常處理的方法,可以使代碼更為簡(jiǎn)潔。
10.測(cè)試要盡可能地小,執(zhí)行速度快。
JUnit和ant結(jié)合
cherami 轉(zhuǎn)貼
ant 提供了兩個(gè) target : junit 和 junitreport
運(yùn)行所有 測(cè)試用例 ,并生成 html 格式的報(bào)表
具體操作如下:
1.將 junit.jar 放在 ANT_HOME\lib 目錄下
2.修改 build.xml ,加入如下 內(nèi)容:
<property name="report" value="report" /> <target name="junitreport" depends="clean, compile"> <junit printsummary="on" fork="true" haltonfailure="false" failureproperty="tests.failed" 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="tests.failed"> --------------------------------------------------------- One or more tests failed, check the report for detail... --------------------------------------------------------- </fail> </target>
運(yùn)行 這個(gè) target ,ant 會(huì)運(yùn)行每個(gè) TestCase
在 report 目錄下就有了 很多 TEST*.xml 和 一些網(wǎng)頁(yè)
打開(kāi) report 目錄下的 index.html 就可以看到很直觀的測(cè)試運(yùn)行報(bào)告,一目了然。
本文來(lái)自: 中國(guó)自學(xué)編程網(wǎng)(www.zxbc.cn) 詳細(xì)出處參考:http://www.zxbc.cn/html/rjgc/1414044315681.htm