JUnit提供了一些輔助函數(shù),用于幫助你確定某個被測試函數(shù)是否工作正常。通常而言,我們把所有這些函數(shù)統(tǒng)稱為斷言。它讓你可以確定:某條件是否為真;兩個數(shù)據(jù)是否相等,或不等,或者其他的一些情況。下面逐個介紹JUnit提供的每一個斷言(assert)方法。
assertEquals(String message, double expected, double actual, double delta)
這是使用得最多的斷言形式。上面的參數(shù)中,expected是你的期望值,actual是被測試代碼實際產(chǎn)生的值,message是一個可選的消息,如果提供的話,將會在發(fā)生錯誤的時候報告這個消息。delta表示精確度。
assertEquals("Should be 3 1/3",3.33,10.0/3.0,0.01)
assertNull
assertNull(String message, Object object)
assertNotNull(String message, Object object)
驗證一個給定的對象是否為null(或者為非null),如果答案為否,則將會失敗。message參數(shù)是可選的。
assertTrue
assertTrue(String message, boolean condition)
驗證給定的二無條件是否為真,如果為假的話,將會失敗。message參數(shù)是可選的。
這種寫法被用于確認某個分支,或者異常邏輯才有可能是正確的選擇。
assertFalse(String message, boolean condition)
驗證給定的二無條件是否為假,如果為真的話,將會失敗。message參數(shù)是可選的。
assertSame
assertSame(String message, Object expected, Object actual)
驗證expected參數(shù)和actual參數(shù)所引用的是否為同一個對象,如果不同的話,將會失敗。message參數(shù)是可選的。
assertNotSame(String message, Object expected, Object actual)
驗證expected參數(shù)和actual參數(shù)所引用的是否為同一個對象,如果相同的話,將會失敗。message參數(shù)是可選的。
fail
fail(String message)
上面的斷言將會使測試立即失敗,其中message參數(shù)是可選的。這種斷言通常被用于標(biāo)記某個不應(yīng)該被到達的分支(例如,在一個預(yù)期發(fā)生的異常之后)。
JUnit測試骨架:
用JUnit寫測試真正所需要的就三件事:
1、一個import語句引入所有JUnit.framework.*下的類。
2、一個extends語句讓你的類從TestCase繼承。
3、一個調(diào)用Super(string)的構(gòu)造函數(shù)。
許多IDE至少會提供這些給你,這樣寫出來的類能夠使用JUnit的test runner運行,并且自動執(zhí)行類中所有的...test方法。
import junit.framework.TestCase;
public class AddtionTest extends TestCase {
public AddtionTest(String name) {
super(name);
}
public void testAdd() {
this.assertEquals(2, 1 + 1);
}
}
定義一個類,每個包含測試的類都必須如所示那樣由TestCase繼承而來。基類TestCase提供了我們所需的大部分單元測試功能,包括所有在前面講述過的斷言方法。
基類需要一個以String為參數(shù)的構(gòu)造函數(shù),因而我們必須調(diào)用super以傳遞這么一個名字。我們不知道這個名字此時是什么,因而我們就僅僅讓我們自己的構(gòu)造函數(shù)接受String參數(shù)并把這個參數(shù)在第五行傳遞上去。
最后,測試類包含了名為XXtest的方法。
JUnit測試組成
一個測試類包含一些測試方法;每個方法包含一個或者多個斷言語句。但是測試類也能調(diào)用其他測試類:單獨的類,包,甚至完整的一個系統(tǒng)。這可能通過創(chuàng)建test suite來取得。任何測試類都能包含一個名為suite的靜態(tài)方法:
public static Test suite();
你可以提供suite()方法來返回任何你想要的測試集合(沒有suite()方法,JUnit會自動運行所有的...test方法)。但是你可能需要手工添加特殊的測試,包括其他suite。
假設(shè)有如下的測試類:
所以我們必須顯示的說明要運行哪個方法。當(dāng)我們調(diào)用test suite的時候,只有那些運行不花多少時間的測試會補運行。而且,此時我們看到了給構(gòu)造函數(shù)的string參數(shù)是做什么用的了:它讓TestCase返回了一個對命名測試方法的引用。這兒,我們使用它來得到那兩個耗時少的方法的引用,它把它們包含到test suite之中。
然后我們再用一個高一級別的測試來組合這兩個測試類:
運行TestClassComposite,以下單個的測試方法都將被運行:
TestClassOne的testAddition()
TestClassOne的testSubtraction()
TestClassTwo的testShortTest()
TestClassTwo的testAnotherShortTest()
每個測試的運行都應(yīng)該是相互獨立的;從而你就可以在任何時候,以任意的順序運行每個單獨的測試。
在調(diào)用每個xxtest方法之前,調(diào)用方法setup();并且在每個測試方法完成之后,調(diào)用方法tearDown()。假設(shè)對于每個測試,你都需要某種數(shù)據(jù)庫連接。這時,你就需要在每個測試方法中重復(fù)建立連接和釋放連接了,而只須在setup和teardown方法中分別建立和釋放連接:public class TestDB extends TestCase {
public TestDB(String name) {
super(name);
}
protected void setUp() throws Exception {
dbconn = new Connection("Oracle", "1521", "fred", "foobar");
dbconn.connect();
}
protected void tearDown() throws Exception {
dbconn.disConnect();
dbconn = null;
}
public void testAccount() {
// use dbconn
}
public void testEmployee() {
// use dbconn
}
}
在上例中,在調(diào)用tessAccount()之前,將會先調(diào)用setup();然后在tessAccount()之后,會接著調(diào)用tearDown()。在第二個測試函數(shù)testEmployee()中,也是按順序先調(diào)用setup(),再調(diào)用該函數(shù),最后調(diào)用tearDown()。
protected void setUp()
protected void tearDown()