作者:Michel Casabianca
使用最流行的開放資源測試框架之一學習單元測試基礎。
使用JUnit可以大量減少Java代碼中程序錯誤的個數,JUnit是一種流行的單元測試框架,用于在發布代碼之前對其進行單元測試。現在讓我們來詳細研究如何使用諸如JUnit、Ant和Oracle9i JDeveloper等工具來編寫和運行單元測試。
為什么使用JUnit?
多數開發人員都同意在發布代碼之前應當對其進行測試,并利用工具進行回歸(regression)測試。做這項工作的一個簡單方法是在所有Java類中以main()方法實施測試。例如,假設使用ISO格式(這意味著有一個以這一格式作為參數的構造器和返回一個格式化的ISO字符串的toString()方法)以及一個GMT時區來編寫一個Date的子類。清單1 就是這個類的一個簡單實現。
不過,這種測試方法并不需要單元測試限定語(qualifier),原因如下:
- 在一個類中進行測試的最小單元是方法,你應當對每個方法進行單獨測試,以準確地找出哪些方法工作正常,哪些方法工作不正常。
- 即使前面的測試失敗,也應當對各個方法進行測試。在此實施中,如果單個測試失敗,后面的測試將根本不會運行。這就意味著你不會知道不良代碼在你的實施中所占的百分比。
- 測試代碼會出現在生成的類中。這在類的大小方面可能不是什么問題,但卻可能會成為安全性因素之一:例如,如果你的測試嵌入了數據庫連接密碼,那么這一信息將很容易用于已發布的類中。
- 沒有框架可以自動啟動這一測試,你必須編寫一個腳本來啟動每一個測試。
- 在編寫一個報告時,你必須編寫自己的實現,并定義規則,以方便地報告錯誤。
JUnit框架就是設計用來解決這些問題的。這一框架主要是所有測試實例(稱為"TestCase")的一個父類,并提供工具來運行所編寫的測試、生成報告及定義測試包(test suite)。
讓我們為IsoDate類編寫一個測試:這個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());
}
}
本例中要注意的重點是已經編寫了一個用于測試的獨立類,因此可以對這些文件進行過濾,以避免將這一代碼嵌入到將要發布的文檔中。另外,本例還為你希望在你的代碼中測試的每個方法編寫了一個專用測試方法,因此你將確切地知道需要對哪些方法進行測試、哪些方法工作正常以及哪些方法工作不正常。如果在編寫實施文檔之前已經編寫了該測試,你就可以利用它來衡量工作的進展情況。
安裝并運行JUnit
要運行此示例測試實例,必須首先下載并安裝JUnit。JUnit的最新版本可以在JUnit的網站 www.junit.org免費下載。該軟件包很小(約400KB),但其中包括了源代碼和文檔。要安裝此程序,應首先對該軟件包進行解壓縮(junitxxx.zip)。它將創建一個目錄(junitxxx),在此目錄下有文檔(在doc目錄中)、框架的應用編程接口(API)文檔(在javadoc目錄中)、運行程序的庫文件(junit.jar)以及示例測試實例(在junit目錄中)。截至我撰寫本文時,JUnit的最新版本為3.8.1,我是在此版本上對示例進行測試的。
圖1 運行IsoDate測試
要運行此測試實例,將源文件(IsoDate.java和IsoDateTest.java)拷貝到Junit的安裝目錄下,打開終端,進入該目錄,然后輸入以下命令行(如果你正在使用UNIX):
export CLASSPATH=.:./junit.jar
javac *.java
或者,如果你正在Windows,輸入以下命令行
set CLASSPATH=.;junit.jar
javac *.java
這些命令行對CLASSPATH進行設置,使其包含當前目錄中的類和junit.jar庫,并編譯Java源文件。
要在終端上運行該測試,輸入以下命令行:
java junit.textui.TestRunner IsoDateTest
此命令行將運行該測試,并在圖 1所示的控制臺上顯示測試結果。
才在此工具可以運行類名被傳遞到命令行中的單個測試。注意:只有對命令行的最后測試才在考慮之內,以前的測試都被忽略了。(看起來像一個程序錯誤,是吧?)
JUnit還提供了利用AWT(抽象窗口工具包)或Swing運行測試的圖形界面。為了利用此圖形界面運行測試,在終端上輸入以下命令行:
java junit.awtui.TestRunner IsoDateTest
或者使用Swing界面:
java junit.swingui.TestRunner IsoDateTest
此命令行將顯示圖 2所示的界面。要選擇一個測試并使其運行,點擊帶有三個點的按鈕。這將顯示CLASSPATH(還有測試包,但我們將在后面討論)中所有測試的列表。要運行測試,點擊"Run"按鈕。測試應當正確運行,并在圖 2所示的界面中顯示結果。
在此界面中你應當選中復選框"Reload Classes Every Run",以便運行器在運行測試類之前對它們進行重新加載。這樣就可以方便地編輯、編譯并運行測試,而不需要每次都啟動圖形界面。
在該復選框下面是一個進度條,在運行較大的測試包時,該進度條非常有用。運行的測試、錯誤和失敗的數量都會在進度條下面顯示出來。再下面是一個失敗列表和一個測試層次結構。失敗消息顯示在底部。通過點擊Test Hierarchy(測試層次結構)面板,然后再點擊窗口右上角的"Run"按鈕,即可運行單個測試方法。請記住,使用命令行工具是不可能做到這些的。
注意,當運行工具來啟動測試類時,這些類必須存在于CLASSPATH中。但是如果測試類存儲在jar文件中,那么即使這些jar文件存在于CLASSPATH中,JUnit也不能找到這些測試類。
圖2 用于運行測試的Swing界面
這并不是一種啟動測試的方便方法,但幸運的是,JUnit已經被集成到了其他工具(如Ant和Oracle9i JDeveloper)中,以幫助你開發測試并使測試能夠自動運行。
編寫Junit測試實例
你已經看到了測試類的源代碼對IsoDate實施進行了詢問。現在讓我們來研究這樣的測試文件的實施。
測試實例由junit.frameword.TestCase繼承而來是為了利用JUnit框架的優點。這個類的名字就是在被測試類的名字上附加"Test"。因為你正在測試一個名為IsoDate的類,所以其測試類的名字就是IsoDateTest。為了訪問除私有方法之外的所有方法,這個類通常與被測類在同一個包中。
注意,你必須為你希望測試的在類中定義的每個方法都編寫一個方法。你要測試構造器或使用了ISO日期格式的方法,因此你將需要為以ISO格式的字符串作為參數的構造器和toString()方法編寫一個測試方法。其命名方式與測試類的命名方式類似:在被測試方法(或構造器)前面附加"test"。
測試方法的主體通過驗證assertion(斷言)對被測方法進行詢問。例如,在toString()實施的測試方法中,你希望確認該方法已經對時間的設定進行了很好的說明(對于UNIX系統來說,最初問世的時間為1970年1月1日的午夜)。要實施assertion,你可以使用Junit框架提供的assertion方法。這些方法在該框架的junit.framework.Assert類中被實施,并且可以在你的測試中被訪問,這是因為Assert是TestCase的父類。這些方法可與Java中的關鍵字assert(是在J2EE 1.4中新出現的)相比。一些assertion方法可以檢查原始類型(如布爾型、整型等)之間或對象之間是否相等(利用equals()方法檢查兩個對象是否相等)。其他assertion方法檢查兩個對象是否相同、一個對象是否為"空"或"非空",以及一個布爾值(通常由一個表達式生成)是"真"還是"假"。在表 1中對這些方法進行了總結。
對于那些采用浮點類型或雙精度類型參數的assertion,存在一個第三種方法,即采用一個delta值作為參數進行比較。另外還要注意,assertEquals()和assertSame()方法一般不會產生相同的結果。(兩個具有相同值的字符串可以不相同,因為它們是兩個具有不同內存地址的不同對象。)因此,assertEquals()將會驗證assertion的有效性,而assertSame()則不會。注意,對于表 1 中的每個assertion方法,你還有一種選擇,就是引入另一個參數,如果assertion失敗,該參數就會給出一條解釋性消息。例如,assertEquals(int 期望值, int 實際值)就可以與一個諸如assertEquals(字符串消息,int期望值,int實際值)的消息一起使用。
當一個assertion失敗時,該assertion方法會拋出一個AssertFailedError或ComparisonFailure。AssertionFailedError由java.lang.Error繼承而來,因此你不必在測試方法的throws語句中對其進行聲明。而ComparisonFailure由AssertionFailedError繼承而來,因此你也不必對其進行聲明。因為當一個assertion失敗時會在測試方法中拋出一個錯誤,所以后面的assertion將不會繼續運行。框架捕捉到這些錯誤并認定該測試已經失敗后,就會打印出一條說明錯誤的消息。這個消息由assertion生成,并且被傳遞到assertion方法(如果有的話)。
現在將下面一行語句添加到testIsoDate()方法的末尾:
assertEquals("This is a test",1,2);
現在編譯并運行測試:
$ javac *.java
$ java junit.textui.TestRunner IsoDateTest
.F.
Time: 0,348
There was 1 failure:
1) testIsoDate(IsoDateTest)junit.framework
.AssertionFailedError: This is a test expected:<1> but was:<2>
at IsoDateTest.testIsoDate
(IsoDateTest.java:29)
FAILURES!!!
Tests run: 2, Failures: 1, Errors: 0
JUnit為每個已處理的測試打印一個點,顯示字母"F"來表示失敗,并在assertion失敗時顯示一條消息。此消息由你發送到assertion方法的注釋和assertion的結果組成(自動生成)。從這里可以看出assertion方法的參數順序對于生成的消息非常重要。第一個參數是期望值,而第二個參數則是實際值。
如果在測試方法中出現了某種錯誤(例如,拋出了一個異常),該工具就會將其顯示為一個錯誤(而不是由assertion失敗而產生的一個"失敗")。現在對IsoDateTest類進行修改,以將前面增加的一行語句用以下語句代替:
throw new Exception("This is a test");
然后編譯并運行測試:
$ javac *.java
$ java junit.textui.TestRunner IsoDateTest
.E.
Time: 0,284
There was 1 error:
1) testIsoDate(IsoDateTest)java.lang.
Exception: This is a test at IsoDate
Test.testIsoDate(IsoDateTest.java:30)
FAILURES!!!
Tests run: 2, Failures: 0, Errors: 1
該工具將該異常顯示為一個錯誤。因此,一個錯誤表示一個錯誤的測試方法,而不是表示一個錯誤的測試實施。
Assert類還包括一個fail()方法(該版本帶有解釋性消息),該方法將通過拋出AssertionFailedError來中斷正在運行的測試。當你希望一個測試失敗而不會調用一個判定方法時,fail()方法是非常有用的。例如,如果一段代碼應當拋出一個異常而未拋出,那么可以調用fail()方法使該測試失敗,方法如下:
public void testIndexOutOfBounds() {
try {
ArrayList list=new ArrayList();
list.get(0);
fail("IndexOutOfBoundsException
not thrown");
} catch(IndexOutOfBoundsException e) {}
}
JUnit的高級特性
在示例測試實例中,你已經同時運行了所有的測試。在現實中,你可能希望運行一個給定的測試方法來詢問你正編寫的實施方法,所以你需要定義一組要運行的測試。這就是框架的junit.framework.TestSuite類的目的,這個類其實只是一個容器,你可以向其中添加一系列測試。如果你正在進行toString()實施,并希望運行相應的測試方法,那么你可以通過重寫測試的suite()方法來通知運行器,方法如下:
public static Test suite() {
TestSuite suite= new TestSuite();
suite.addTest(new IsoDateTest
("testToString"));
return suite;
}
在此方法中,你用具體示例說明了一個TestSuite對象,并向其中添加了測試。為了在方法級定義測試,你可以利用構造器將方法名作為參數使測試類實例化。此構造器可按如下方法實施:
public IsoDateTest(String name) {
super(name);
}
將上面的構造器和方法添加到IsoDateTest類(還需要引入junit.framework.Test和junit.framework.TestSuite),并在終端上輸入:
圖3:選擇一個測試方法
$ javac *.java
$ java junit.textui.TestRunner IsoDateTest
.
Time: 0,31
OK (1 test)
注意,在添加到測試包中的測試方法中,只運行了一個測試方法,即toString()方法。
你也可以利用圖形界面,通過在圖3所示的Test Hierarchy面板中選擇測試方法來運行一個給定的測試方法。但是,要注意當整個測試包被運行一次后,該面板將被填滿。
當你希望將一個測試實例中的所有測試方法添加到一個TestSuite對象中時,可以使用一個專用構造器,該構造器將此測試實例的類對象作為參數。例如,你可以使用IsoDateTest類實施suite()方法,方法如下:
public static Test suite() {
return new TestSuite(IsoDateTest.class);
}
還有一些情況,你可能希望運行一組由其他測試(如在工程發布之前的所有測試)組成的測試。在這種情況下,你必須編寫一個實施suite()方法的類,以建立希望運行的測試包。例如,假定你已經編寫了測試類Atest和Btest。為了定義那些包含了類ATest中的所有測試和在BTest中定義的測試包的集合,可以編寫下面的類:
import junit.framework.*;
/**
* TestSuite that runs all tests.
*/
public class AllTests {
public static Test suite() {
TestSuite suite= new TestSuite("All Tests");
suite.addTestSuite(ATest.class);
suite.addTest(BTest.suite());
return suite;
}
}
你完全可以像運行單個測試實例那樣運行這個測試包。注意,如果一個測試在一個套件中添加了兩次,那么運行器將運行它兩次(測試包和運行器都不會檢查該測試是否是唯一的)。為了了解實際的測試包的實施,應當研究Junit本身的測試包。這些類的源代碼存在于JUnit安裝的junit/test目錄下。
圖4:顯示測試結果的報告
將一個main()方法添加到一個測試或一個測試包中有時是非常方便的,因此可以在不使用運行器的情況下啟動測試。例如,要將AllTests測試包作為一個標準的Java程序啟動,可以將下面的main()方法添加到類中:
public static void main(String[] args) {
junit.textui.TestRunner.run(suite());
}
現在可以通過輸入java AllTests來啟動這個測試包。
JUnit框架還提供了一種有效利用代碼的方法,即將資源集合到被稱為fixture的對象集中。例如,該示例測試實例利用兩個叫作epoch和eon的參考日期。將這些日期重新編譯到每個方法測試中只是浪費時間(而且還可能出現錯誤)。你可以用fixture重新編寫測試,如清單2所示。
你定義了兩個參考日期,作為測試類的段,并將它們編譯到一個setUp()方法中。這一方法在每個測試方法之前被調用。與其對應的方法是tearDown()方法,它將在每個測試方法運行之后清除所有的資源(在這個實施中,該方法事實上什么也沒做,因為垃圾收集器為我們完成了這項工作)。現在編譯這個測試實例(其源代碼應當放在JUnit的安裝目錄中)并運行它:
$ javac *.java
$ java junit.textui.TestRunner IsoDateTest2
.setUp()
testIsoDate()
tearDown()
.setUp()
testToString()
tearDown()
Time: 0,373
OK (2 tests)
注意:在該測試實例中建立了參考日期,因此在任何測試方法中修改這些日期都不會對其他測試產生不利影響。你可以將代碼放到這兩個方法中,以建立和釋放每個測試所需要的資源(如數據庫連接)。
JUnit發布版還提供了擴展模式(在包junit.extensions中),即test decor-ators,以提供像重復運行一個給定的測試這樣的新功能。它還提供了一個TestSuite,以方便你在獨立的線程中同時運行所有測試,并在所有線程中的測試都完成時停止。
利用Ant使測試自動化
如前面所述,測試運行器是非常原始的。如果你正在運行Ant來編譯你的工程,那么編譯文件是運行單元測試的好方法。(關于Ant的介紹,請參考我的文章《Ant簡介》(Starting with Ant),發表于Oracle雜志2002年11/12月號中)。
假設你的源文件在src目錄中,所生成的類在tmp目錄中,并且junit.jar庫位于工程的libdirectory目錄中,那么你可以編譯Java源文件,并使用清單3中所示的編譯文件(在工程的根目錄中)運行單元測試。
這個編譯文件的核心是運行單元測試的測試目標。運行這些測試是這個目標junit的唯一任務。為了運行這一可選任務,必須首先將junit.jar庫放到Ant安裝目錄下的lib目錄中,然后下載并安裝同一目錄中的Ant可選任務庫。清單3中的示例嵌套了一個classpath類,它包括JUnit庫和工程的類;示例中還嵌套了一個batchtest元素,它利用一個選擇適當源文件的fileset元素定義了將要運行的測試。這個任務還包括haltonfilure和haltonerror屬性,它們告訴Ant在遇到一個失敗或錯誤時是否應當停止。如果將它們的值設置為"真",那么Ant在遇到第一個失敗或錯誤時將會停止,編譯將會失敗(顯然,這表示在運行測試過程中存在有問題)。另一方面,如果將它們的值設置為"假",其結果就不是非常明確了(即使測試失敗,編譯也會成功),但所有測試仍將運行。printsummary屬性指示Ant是否顯示運行測試的輸出。數值withOutAndErr可以在開發測試時方便地告訴Ant顯示標準輸出和錯誤輸出。數值off表示不顯示任何內容,而on只顯示測試報告(沒有測試類的輸出)。junit任務具有很多屬性,詳細內容請參考Ant的文檔。
為了測試這一編譯文件,你需要建立名字為src、tmp和lib的目錄。將junit.jar庫放到lib目錄中,并將前面看到的示例Java源文件放到src目錄中。打開終端,進入該工程的根目錄,并輸入ant,其結果為:
$ 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格式的測試報告。為了生成這樣的報告,將前面的測試目標用以下目標代替:
<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>
這一目標與前面的目標相同,只是該目標在batchtext元素中增加了一個新的屬性--todir,它告訴Ant在tmp目錄中生成可擴展的標記語言(XML)報告。該目標還增加了一個新的junitreport元素,以便由XML文件生成一個HTML報告。這一元素要求在安裝Ant的lib目錄中安裝Xalan庫(詳細內容見Ant文檔的junitreport部分:ant.apache.org/manual/install.html)。這一元素還定義了使用todir屬性生成的文件的目標目錄。通過嵌套一個fileset元素來定義為生成這一報告而需要處理的XML文件。期望的輸出格式利用嵌套的報告元素來實現。該對象將生成一個諸如圖4所示的報告。
這類報告在使單元測試自動運行時特別有用(比如在夜間編譯期間)。在這些情況下,錯誤或失敗不會中斷測試,因此你必須將前面提到的junit任務的haltonfailure和haltonerror屬性設置為"假"。這一報告對于衡量實施進程也非常有用(比如當你必須重寫已有代碼時,或者在實施之前已經編寫了測試的情況下)。
Ant對啟動JUnit圖形運行器也非常有用。下面的對象將會啟動Swing測試運行器:
<target name="testui" depends="bin"
description="Run graphical JUnit">
<java classname="junit.swingui.TestRunner"
classpathref="cp"
fork="true"/>
</target>
你應當在終端中運行這一對象,并且在另一個終端或你喜歡的IDE中使用Ant對其進行編譯。這種方式使你不必在每次想要測試代碼時都啟動圖形運行器。
在Oracle9i Jdeveloper中的JUnit集成
Oracle9i JDeveloper并沒有基于網絡集成JUnit,但是下載并安裝這一插件只需要幾分鐘的時間。為了完成此過程,選擇JDeveloper的"Help"菜單下的"Check for Updates"項。這樣將會打開IDE更新向導,以連接到Oracle技術網站,下載該插件并安裝它。當安裝該插件后,需要關閉并重啟Oracle9i JDeveloper。注意,向導還會下載相關的文檔。
通過為每個任務提供向導,這個插件極大地提高了開發人員編寫測試實例、測試包和fixture等的工作效率。要調用這些向導,點擊"File"菜單下的"New"項,然后選擇"General/Unit Tests"類,并從右側的窗體中選擇合適的向導。你也可以從界面上啟動測試套件。
當準備好對項目進行代碼測試后,應當首先使用專用向導來編寫fixture,然后測試實例向導可以利用它們集成到測試實例中。另外,還有一些用來生成自定義測試fixture的向導以及生成商務組件和數據庫連接測試fixture的向導。這后兩種向導生成專用代碼,以使用setUp()和tearDown()方法設置和發布商務組件或數據庫連接。
當完成fixture后,下一步應當使用合適的向導來生成測試實例,這些向導可以讓你選擇要測試的類和方法。你還可以選擇在這個測試中使用的fixture。這將生成一個使用測試方法的主體完成的代碼框架。最后應當生成套件來運行你的測試。這個專用向導讓你選擇要包括在套件中的測試,并為你生成整個類。要啟動一個測試套件,點擊瀏覽器中的文件,并選擇Run。這將會啟動圖形界面并運行套件的測試。
在"Help"菜單中選擇"Help Topics",你將會在JDeveloper文檔中找到關于如何使用這些向導的詳細教程。這會打開幫助系統窗口。點擊"Unit Testing with JUnit"項,然后選擇合適的教程。
JUnit和JDeveloper之間的這種集成使你能夠只編寫單元測試中你感興趣的那部分的代碼,而讓工具為你編寫重復的代碼。
JUnit最佳實踐
下面是一些在使用JUnit時應當注意的技巧:
- 在實施之前編寫測試代碼。這是一種合同驅動的實施方式。
- 只測試那些可能會中斷的方法(也就是說,在多數情況下不應測試setter和getter方法)。要盡可能地多進行測試,以避免回歸測試。當測試一個較大的應用程序時,你可以在夜間編譯時運行所有測試。
- 一定要使用正確的JUnit擴展來測試特殊的應用程序(如使用Castus測試J2EE應用程序)。
值得花費的時間
到現在,你應當已經清楚地知道使用JUnit框架和合適的工具實施單元測試是多么快速而簡單。關于單元測試的下一個目標是使你的CTO相信你在實施測試時所必須花費的時間是為了以后節省更多的時間。但是,當你考慮在檢查老代碼、修正錯誤和發布一個調試過的版本上所花費的時間(它可能花費整個一天)時,在開發過程的早期階段捕獲的代碼錯誤毫無疑問是一項很好的投資。這里并沒有考慮當錯誤代碼不再位于塊的頂部時開發人員必須遵循的"black magic"步驟,這些步驟包括:標記代碼,制作一個分支、修正代碼錯誤、進行發布,以及將代碼修正合并到塊中。所有這些步驟都非常耗時,并且容易產生錯誤。
要開始使用單元測試和JUnit,請訪問JUnit網站: www.junit.org。你將找到大量有用的文檔(包括使用JUnit實施測試的詳細說明書)、一個與JUnit集成的IDE列表,以及關于JUnit擴展工具的詳細內容。
Michel Casabianca ( casa@sweetohm.net)是In-Fusio(一家為移動用戶提供游戲服務的法國公司)的一名軟件工程師,同時也是XML Pocket Reference(O'Reilly出版,2001年)一書的合著者。
表1:編寫測試實例中所使用的判定方法
|
assertEquals(期望原型,實際原型) |
檢查兩個原型是否相等 |
assertEquals(期望對象,實際對象) |
利用對象的equals()方法檢查兩個對象是否相等 |
assertSame(期望對象,實際對象) |
檢查具有相同內存地址的兩個對象是否相等 |
assertNotSame(期望對象,實際對象) |
檢查具有不同內存地址的兩個對象是否不相等 |
assertNull(對象 對象) |
檢查一個對象是否為空 |
assertNotNull(對象 對象) |
檢查一個對象是否為非空 |
assertTrue(布爾條件) |
檢查條件是否為真 |
assertFalse(布爾條件) |
檢查條件是否為假 | | | | |
 |
 |