使用JUnit可以大量減少Java代碼中程序錯(cuò)誤的個(gè)數(shù),JUnit是一種流行的單元測(cè)試框架,用于在發(fā)布代碼之前對(duì)其進(jìn)行單元測(cè)試,F(xiàn)在讓我們來(lái)詳細(xì)研究如何使用諸如JUnit、Ant和Oracle9i JDeveloper等工具來(lái)編寫(xiě)和運(yùn)行單元測(cè)試。
為什么使用JUnit?
多數(shù)開(kāi)發(fā)人員都同意在發(fā)布代碼之前應(yīng)當(dāng)對(duì)其進(jìn)行測(cè)試,并利用工具進(jìn)行回歸(regression)測(cè)試。做這項(xiàng)工作的一個(gè)簡(jiǎn)單方法是在所有Java類中以main()方法實(shí)施測(cè)試。例如,假設(shè)使用ISO格式(這意味著有一個(gè)以這一格式作為參數(shù)的構(gòu)造器和返回一個(gè)格式化的ISO字符串的toString()方法)以及一個(gè)GMT時(shí)區(qū)來(lái)編寫(xiě)一個(gè)Date的子類。清單1 是這個(gè)類的一個(gè)簡(jiǎn)單實(shí)現(xiàn)。
不過(guò),這種測(cè)試方法并不需要單元測(cè)試限定語(yǔ)(qualifier),原因如下:
在一個(gè)類中進(jìn)行測(cè)試的小單元是方法,你應(yīng)當(dāng)對(duì)每個(gè)方法進(jìn)行單獨(dú)測(cè)試,以準(zhǔn)確地找出哪些方法工作正常,哪些方法工作不正常。
即使前面的測(cè)試失敗,也應(yīng)當(dāng)對(duì)各個(gè)方法進(jìn)行測(cè)試。在此實(shí)施中,如果單個(gè)測(cè)試失敗,后面的測(cè)試將根本不會(huì)運(yùn)行。這意味著你不會(huì)知道不良代碼在你的實(shí)施中所占的百分比。
測(cè)試代碼會(huì)出現(xiàn)在生成的類中。這在類的大小方面可能不是什么問(wèn)題,但卻可能會(huì)成為安全性因素之一:例如,如果你的測(cè)試嵌入了數(shù)據(jù)庫(kù)連接密碼,那么這一信息將很容易用于已發(fā)布的類中。
沒(méi)有框架可以自動(dòng)啟動(dòng)這一測(cè)試,你必須編寫(xiě)一個(gè)腳本來(lái)啟動(dòng)每一個(gè)測(cè)試。
在編寫(xiě)一個(gè)報(bào)告時(shí),你必須編寫(xiě)自己的實(shí)現(xiàn),并定義規(guī)則,以方便地報(bào)告錯(cuò)誤。
JUnit框架是設(shè)計(jì)用來(lái)解決這些問(wèn)題的。這一框架主要是所有測(cè)試實(shí)例(稱為"TestCase")的一個(gè)父類,并提供工具來(lái)運(yùn)行所編寫(xiě)的測(cè)試、生成報(bào)告及定義測(cè)試包(test suite)。
讓我們?yōu)镮soDate類編寫(xiě)一個(gè)測(cè)試:這個(gè)IsoDateTest類類似于:
import java.text.ParseException;
import junit.framework.TestCase;
/**
* Test case for <code>IsoDate</code>.
*/
public class IsoDateTest extends TestCase {
public void testIsoDate() throws
Exception {
IsoDate epoch=new IsoDate(
"1970-01-01 00:00:00 GMT");
assertEquals(0,epoch.getTime());
IsoDate eon=new IsoDate(
"2001-09-09 01:46:40 GMT");
assertEquals(
1000000000L*1000,eon.getTime());
}
public void testToString() throws
ParseException {
IsoDate epoch=new IsoDate(0);
assertEquals("1970-01-01
00:00:00 GMT",epoch.toString());
IsoDate eon=new IsoDate(
1000000000L*1000);
assertEquals("2001-09-09
01:46:40 GMT",eon.toString());
}
}
本例中要注意的重點(diǎn)是已經(jīng)編寫(xiě)了一個(gè)用于測(cè)試的獨(dú)立類,因此可以對(duì)這些文件進(jìn)行過(guò)濾,以避免將這一代碼嵌入到將要發(fā)布的文檔中。另外,本例還為你希望在你的代碼中測(cè)試的每個(gè)方法編寫(xiě)了一個(gè)專用測(cè)試方法,因此你將確切地知道需要對(duì)哪些方法進(jìn)行測(cè)試、哪些方法工作正常以及哪些方法工作不正常。如果在編寫(xiě)實(shí)施文檔之前已經(jīng)編寫(xiě)了該測(cè)試,你可以利用它來(lái)衡量工作的進(jìn)展情況。
安裝并運(yùn)行JUnit
要運(yùn)行此示例測(cè)試實(shí)例,必須首先下載并安裝JUnit。JUnit的新版本可以在JUnit的網(wǎng)站www.junit.org免費(fèi)下載。該軟件包很。s400KB),但其中包括了源代碼和文檔。要安裝此程序,應(yīng)首先對(duì)該軟件包進(jìn)行解壓縮(junitxxx.zip)。它將創(chuàng)建一個(gè)目錄(junitxxx),在此目錄下有文檔(在doc目錄中)、框架的應(yīng)用編程接口(API)文檔(在javadoc目錄中)、運(yùn)行程序的庫(kù)文件(junit.jar)以及示例測(cè)試實(shí)例(在junit目錄中)。截至我撰寫(xiě)本文時(shí),JUnit的新版本為3.8.1,我是在此版本上對(duì)示例進(jìn)行測(cè)試的。