為了測試這一編譯文件,你需要建立名字為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格式的測試報告。為了生成這樣的報告,將前面的測試目標(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元素中增加了一個新的屬性--todir,它告訴Ant在tmp目錄中生成可擴(kuò)展的標(biāo)記語言(XML)報告。該目標(biāo)還增加了一個新的junitreport元素,以便由XML文件生成一個HTML報告。這一元素要求在安裝Ant的lib目錄中安裝Xalan庫(詳細(xì)內(nèi)容見Ant文檔的junitreport部分:ant.apache.org/manual/install.html)。這一元素還定義了使用todir屬性生成的文件的目標(biāo)目錄。通過嵌套一個fileset元素來定義為生成這一報告而需要處理的XML文件。期望的輸出格式利用嵌套的報告元素來實(shí)現(xiàn)。該對象將生成一個諸如圖4所示的報告。
這類報告在使單元測試自動運(yùn)行時特別有用(比如在夜間編譯期間)。在這些情況下,錯誤或失敗不會中斷測試,因此你必須將前面提到的junit任務(wù)的haltonfailure和haltonerror屬性設(shè)置為"假"。這一報告對于衡量實(shí)施進(jìn)程也非常有用(比如當(dāng)你必須重寫已有代碼時,或者在實(shí)施之前已經(jīng)編寫了測試的情況下)。
Ant對啟動JUnit圖形運(yùn)行器也非常有用。下面的對象將會啟動Swing測試運(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)行這一對象,并且在另一個終端或你喜歡的IDE中使用Ant對其進(jìn)行編譯。這種方式使你不必在每次想要測試代碼時都啟動圖形運(yùn)行器。
在Oracle9i Jdeveloper中的JUnit集成
Oracle9i JDeveloper并沒有基于網(wǎng)絡(luò)集成JUnit,但是下載并安裝這一插件只需要幾分鐘的時間。為了完成此過程,選擇JDeveloper的"Help"菜單下的"Check for Updates"項(xiàng)。這樣將會打開IDE更新向?qū),以連接到Oracle技術(shù)網(wǎng)站,下載該插件并安裝它。當(dāng)安裝該插件后,需要關(guān)閉并重啟Oracle9i JDeveloper。注意,向?qū)н會下載相關(guān)的文檔。
通過為每個任務(wù)提供向?qū),這個插件極大地提高了開發(fā)人員編寫測試實(shí)例、測試包和fixture等的工作效率。要調(diào)用這些向?qū),點(diǎn)擊"File"菜單下的"New"項(xiàng),然后選擇"General/Unit Tests"類,并從右側(cè)的窗體中選擇合適的向?qū)。你也可以從界面上啟動測試套件。
當(dāng)準(zhǔn)備好對項(xiàng)目進(jìn)行代碼測試后,應(yīng)當(dāng)首先使用專用向?qū)砭帉慺ixture,然后測試實(shí)例向?qū)Э梢岳盟鼈兗傻綔y試實(shí)例中。另外,還有一些用來生成自定義測試fixture的向?qū)б约吧缮虅?wù)組件和數(shù)據(jù)庫連接測試fixture的向?qū)。這后兩種向?qū)蓪S么a,以使用setUp()和tearDown()方法設(shè)置和發(fā)布商務(wù)組件或數(shù)據(jù)庫連接。
當(dāng)完成fixture后,下一步應(yīng)當(dāng)使用合適的向?qū)砩蓽y試實(shí)例,這些向?qū)Э梢宰屇氵x擇要測試的類和方法。你還可以選擇在這個測試中使用的fixture。這將生成一個使用測試方法的主體完成的代碼框架。后應(yīng)當(dāng)生成套件來運(yùn)行你的測試。這個專用向?qū)ё屇氵x擇要包括在套件中的測試,并為你生成整個類。要啟動一個測試套件,點(diǎn)擊瀏覽器中的文件,并選擇Run。這將會啟動圖形界面并運(yùn)行套件的測試。
在"Help"菜單中選擇"Help Topics",你將會在JDeveloper文檔中找到關(guān)于如何使用這些向?qū)У脑敿?xì)教程。這會打開幫助系統(tǒng)窗口。點(diǎn)擊"Unit Testing with JUnit"項(xiàng),然后選擇合適的教程。
	JUnit和JDeveloper之間的這種集成使你能夠只編寫單元測試中你感興趣的那部分的代碼,而讓工具為你編寫重復(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時應(yīng)當(dāng)注意的技巧:
	    在實(shí)施之前編寫測試代碼。這是一種合同驅(qū)動的實(shí)施方式。
	    只測試那些可能會中斷的方法(也是說,在多數(shù)情況下不應(yīng)測試setter和getter方法)。要盡可能地多進(jìn)行測試,以避免回歸測試。當(dāng)測試一個較大的應(yīng)用程序時,你可以在夜間編譯時運(yùn)行所有測試。
	    一定要使用正確的JUnit擴(kuò)展來測試特殊的應(yīng)用程序(如使用Castus測試J2EE應(yīng)用程序)。
值得花費(fèi)的時間
到現(xiàn)在,你應(yīng)當(dāng)已經(jīng)清楚地知道使用JUnit框架和合適的工具實(shí)施單元測試是多么快速而簡單。關(guān)于單元測試的下一個目標(biāo)是使你的CTO相信你在實(shí)施測試時所必須花費(fèi)的時間是為了以后節(jié)省更多的時間。但是,當(dāng)你考慮在檢查老代碼、修正錯誤和發(fā)布一個調(diào)試過的版本上所花費(fèi)的時間(它可能花費(fèi)整個)時,在開發(fā)過程的早期階段捕獲的代碼錯誤毫無疑問是一項(xiàng)很好的投資。這里并沒有考慮當(dāng)錯誤代碼不再位于塊的頂部時開發(fā)人員必須遵循的"black magic"步驟,這些步驟包括:標(biāo)記代碼,制作一個分支、修正代碼錯誤、進(jìn)行發(fā)布,以及將代碼修正合并到塊中。所有這些步驟都非常耗時,并且容易產(chǎn)生錯誤。
要開始使用單元測試和JUnit,請?jiān)L問JUnit網(wǎng)站:www.junit.org。你將找到大量有用的文檔(包括使用JUnit實(shí)施測試的詳細(xì)說明書)、一個與JUnit集成的IDE列表,以及關(guān)于JUnit擴(kuò)展工具的詳細(xì)內(nèi)容。
Michel Casabianca ( casa@sweetohm.net)是In-Fusio(一家為移動用戶提供游戲服務(wù)的法國公司)的一名軟件工程師,同時也是XML Pocket Reference(O'Reilly出版,2001年)一書的合著者。
表1:編寫測試實(shí)例中所使用的判定方法
	assertEquals(期望原型,實(shí)際原型)  檢查兩個原型是否相等
	assertEquals(期望對象,實(shí)際對象)  利用對象的equals()方法檢查兩個對象是否相等
	assertSame(期望對象,實(shí)際對象)  檢查具有相同內(nèi)存地址的兩個對象是否相等
	assertNotSame(期望對象,實(shí)際對象)  檢查具有不同內(nèi)存地址的兩個對象是否不相等
	assertNull(對象 對象)  檢查一個對象是否為空
	assertNotNull(對象 對象)  檢查一個對象是否為非空
	assertTrue(布爾條件)  檢查條件是否為真
	assertFalse(布爾條件)  檢查條件是否為假