為了測(cè)試這一編譯文件,你需要建立名字為src、tmp和lib的目錄。將junit.jar庫放到lib目錄中,并將前面看到的示例Java源文件放到src目錄中。打開終端,進(jìn)入該工程的根目錄,并輸入ant,其結(jié)果為:
$ ant
Buildfile: build.xml
clean:
[delete] Deleting directory
/Users/casa/doc/oracle
/junit/prj/tmp
[mkdir] Created dir: /Users/casa
/doc/oracle/junit/prj/tmp
bin:
[javac] Compiling 4 source files
to /Users/casa/doc/oracle
/junit/prj/tmp
test:
[junit] Running IsoDateTest
[junit] Tests run: 1, Failures:
0, Errors: 0, Time elapsed:
0,005 sec
[junit] Running IsoDateTest2
[junit] Tests run: 2, Failures: 0,
Errors: 0, Time elapsed: 0,031 sec
[junit] Output:
[junit] setUp()
[junit] testIsoDate()
[junit] tearDown()
[junit] setUp()
[junit] testToString()
[junit] tearDown()
all:
BUILD SUCCESSFUL
Total time: 8 seconds
Ant還可以生成非常有用的HTML格式的測(cè)試報(bào)告。為了生成這樣的報(bào)告,將前面的測(cè)試目標(biāo)用以下目標(biāo)代替:
<target name="test" depends="bin"
description="Run JUnit tests">
<junit haltonfailure="false"
printsummary="withOutAndErr">
<classpath refid="cp"/>
<batchtest todir="${tmp}">
<fileset dir="${src}"
includes="**/*Test*.java"/>
</batchtest>
<formatter type="xml"/>
</junit>
<junitreport todir="${tmp}">
<fileset dir="${tmp}"
includes="TEST-*.xml"/>
<report format="frames"
todir="${tmp}"/>
</junitreport>
</target>
這一目標(biāo)與前面的目標(biāo)相同,只是該目標(biāo)在batchtext元素中增加了一個(gè)新的屬性--todir,它告訴Ant在tmp目錄中生成可擴(kuò)展的標(biāo)記語言(XML)報(bào)告。該目標(biāo)還增加了一個(gè)新的junitreport元素,以便由XML文件生成一個(gè)HTML報(bào)告。這一元素要求在安裝Ant的lib目錄中安裝Xalan庫(詳細(xì)內(nèi)容見Ant文檔的junitreport部分:ant.apache.org/manual/install.html)。這一元素還定義了使用todir屬性生成的文件的目標(biāo)目錄。通過嵌套一個(gè)fileset元素來定義為生成這一報(bào)告而需要處理的XML文件。期望的輸出格式利用嵌套的報(bào)告元素來實(shí)現(xiàn)。該對(duì)象將生成一個(gè)諸如圖4所示的報(bào)告。
這類報(bào)告在使單元測(cè)試自動(dòng)運(yùn)行時(shí)特別有用(比如在夜間編譯期間)。在這些情況下,錯(cuò)誤或失敗不會(huì)中斷測(cè)試,因此你必須將前面提到的junit任務(wù)的haltonfailure和haltonerror屬性設(shè)置為"假"。這一報(bào)告對(duì)于衡量實(shí)施進(jìn)程也非常有用(比如當(dāng)你必須重寫已有代碼時(shí),或者在實(shí)施之前已經(jīng)編寫了測(cè)試的情況下)。
Ant對(duì)啟動(dòng)JUnit圖形運(yùn)行器也非常有用。下面的對(duì)象將會(huì)啟動(dòng)Swing測(cè)試運(yùn)行器:
<target name="testui" depends="bin"
description="Run graphical JUnit">
<java classname="junit.swingui.TestRunner"
classpathref="cp"
fork="true"/>
</target>
你應(yīng)當(dāng)在終端中運(yùn)行這一對(duì)象,并且在另一個(gè)終端或你喜歡的IDE中使用Ant對(duì)其進(jìn)行編譯。這種方式使你不必在每次想要測(cè)試代碼時(shí)都啟動(dòng)圖形運(yùn)行器。
在Oracle9i Jdeveloper中的JUnit集成
Oracle9i JDeveloper并沒有基于網(wǎng)絡(luò)集成JUnit,但是下載并安裝這一插件只需要幾分鐘的時(shí)間。為了完成此過程,選擇JDeveloper的"Help"菜單下的"Check for Updates"項(xiàng)。這樣將會(huì)打開IDE更新向?qū),以連接到Oracle技術(shù)網(wǎng)站,下載該插件并安裝它。當(dāng)安裝該插件后,需要關(guān)閉并重啟Oracle9i JDeveloper。注意,向?qū)н會(huì)下載相關(guān)的文檔。
通過為每個(gè)任務(wù)提供向?qū),這個(gè)插件極大地提高了開發(fā)人員編寫測(cè)試實(shí)例、測(cè)試包和fixture等的工作效率。要調(diào)用這些向?qū),點(diǎn)擊"File"菜單下的"New"項(xiàng),然后選擇"General/Unit Tests"類,并從右側(cè)的窗體中選擇合適的向?qū)АD阋部梢詮慕缑嫔蠁?dòng)測(cè)試套件。
當(dāng)準(zhǔn)備好對(duì)項(xiàng)目進(jìn)行代碼測(cè)試后,應(yīng)當(dāng)首先使用專用向?qū)砭帉慺ixture,然后測(cè)試實(shí)例向?qū)Э梢岳盟鼈兗傻綔y(cè)試實(shí)例中。另外,還有一些用來生成自定義測(cè)試fixture的向?qū)б约吧缮虅?wù)組件和數(shù)據(jù)庫連接測(cè)試fixture的向?qū)А_@后兩種向?qū)蓪S么a,以使用setUp()和tearDown()方法設(shè)置和發(fā)布商務(wù)組件或數(shù)據(jù)庫連接。
當(dāng)完成fixture后,下一步應(yīng)當(dāng)使用合適的向?qū)砩蓽y(cè)試實(shí)例,這些向?qū)Э梢宰屇氵x擇要測(cè)試的類和方法。你還可以選擇在這個(gè)測(cè)試中使用的fixture。這將生成一個(gè)使用測(cè)試方法的主體完成的代碼框架。后應(yīng)當(dāng)生成套件來運(yùn)行你的測(cè)試。這個(gè)專用向?qū)ё屇氵x擇要包括在套件中的測(cè)試,并為你生成整個(gè)類。要啟動(dòng)一個(gè)測(cè)試套件,點(diǎn)擊瀏覽器中的文件,并選擇Run。這將會(huì)啟動(dòng)圖形界面并運(yùn)行套件的測(cè)試。
在"Help"菜單中選擇"Help Topics",你將會(huì)在JDeveloper文檔中找到關(guān)于如何使用這些向?qū)У脑敿?xì)教程。這會(huì)打開幫助系統(tǒng)窗口。點(diǎn)擊"Unit Testing with JUnit"項(xiàng),然后選擇合適的教程。
JUnit和JDeveloper之間的這種集成使你能夠只編寫單元測(cè)試中你感興趣的那部分的代碼,而讓工具為你編寫重復(fù)的代碼。
下一步
訪問JUnit網(wǎng)站
www.junit.org
下載
Oracle9i Jdeveloper
otn.oracle.com/software/products/jdev/
Oracle9i應(yīng)用服務(wù)器
otn.oracle.com/software/products/ias/
學(xué)習(xí)Oracle9i JDeveloper擴(kuò)展
otn.oracle.com/products/jdev/htdocs/partners/addins
閱讀Oracle9i JDeveloper文檔
otn.oracle.com/docs/products/jdev/
JUnit佳實(shí)踐
下面是一些在使用JUnit時(shí)應(yīng)當(dāng)注意的技巧:
在實(shí)施之前編寫測(cè)試代碼。這是一種合同驅(qū)動(dòng)的實(shí)施方式。
只測(cè)試那些可能會(huì)中斷的方法(也是說,在多數(shù)情況下不應(yīng)測(cè)試setter和getter方法)。要盡可能地多進(jìn)行測(cè)試,以避免回歸測(cè)試。當(dāng)測(cè)試一個(gè)較大的應(yīng)用程序時(shí),你可以在夜間編譯時(shí)運(yùn)行所有測(cè)試。
一定要使用正確的JUnit擴(kuò)展來測(cè)試特殊的應(yīng)用程序(如使用Castus測(cè)試J2EE應(yīng)用程序)。
值得花費(fèi)的時(shí)間
到現(xiàn)在,你應(yīng)當(dāng)已經(jīng)清楚地知道使用JUnit框架和合適的工具實(shí)施單元測(cè)試是多么快速而簡單。關(guān)于單元測(cè)試的下一個(gè)目標(biāo)是使你的CTO相信你在實(shí)施測(cè)試時(shí)所必須花費(fèi)的時(shí)間是為了以后節(jié)省更多的時(shí)間。但是,當(dāng)你考慮在檢查老代碼、修正錯(cuò)誤和發(fā)布一個(gè)調(diào)試過的版本上所花費(fèi)的時(shí)間(它可能花費(fèi)整個(gè))時(shí),在開發(fā)過程的早期階段捕獲的代碼錯(cuò)誤毫無疑問是一項(xiàng)很好的投資。這里并沒有考慮當(dāng)錯(cuò)誤代碼不再位于塊的頂部時(shí)開發(fā)人員必須遵循的"black magic"步驟,這些步驟包括:標(biāo)記代碼,制作一個(gè)分支、修正代碼錯(cuò)誤、進(jìn)行發(fā)布,以及將代碼修正合并到塊中。所有這些步驟都非常耗時(shí),并且容易產(chǎn)生錯(cuò)誤。
要開始使用單元測(cè)試和JUnit,請(qǐng)?jiān)L問JUnit網(wǎng)站:www.junit.org。你將找到大量有用的文檔(包括使用JUnit實(shí)施測(cè)試的詳細(xì)說明書)、一個(gè)與JUnit集成的IDE列表,以及關(guān)于JUnit擴(kuò)展工具的詳細(xì)內(nèi)容。
Michel Casabianca ( casa@sweetohm.net)是In-Fusio(一家為移動(dòng)用戶提供游戲服務(wù)的法國公司)的一名軟件工程師,同時(shí)也是XML Pocket Reference(O'Reilly出版,2001年)一書的合著者。
表1:編寫測(cè)試實(shí)例中所使用的判定方法
assertEquals(期望原型,實(shí)際原型) 檢查兩個(gè)原型是否相等
assertEquals(期望對(duì)象,實(shí)際對(duì)象) 利用對(duì)象的equals()方法檢查兩個(gè)對(duì)象是否相等
assertSame(期望對(duì)象,實(shí)際對(duì)象) 檢查具有相同內(nèi)存地址的兩個(gè)對(duì)象是否相等
assertNotSame(期望對(duì)象,實(shí)際對(duì)象) 檢查具有不同內(nèi)存地址的兩個(gè)對(duì)象是否不相等
assertNull(對(duì)象 對(duì)象) 檢查一個(gè)對(duì)象是否為空
assertNotNull(對(duì)象 對(duì)象) 檢查一個(gè)對(duì)象是否為非空
assertTrue(布爾條件) 檢查條件是否為真
assertFalse(布爾條件) 檢查條件是否為假