1.初級(jí)篇
1.1 單元測(cè)試
我們?cè)诰帉懘笮统绦虻臅r(shí)候意推,需要寫成千上萬個(gè)方法或函數(shù)豆瘫,這些函數(shù)的功能可能很強(qiáng)大,但我們?cè)诔绦蛑兄挥玫皆摵瘮?shù)的一小部分功能菊值,并且經(jīng)過調(diào)試可以確定外驱,這一小部分功能是正確的育灸。但是,我們同時(shí)應(yīng)該確保每一個(gè)函數(shù)都完全正確昵宇,因?yàn)槿绻覀兘窈笕绻麑?duì)程序進(jìn)行擴(kuò)展磅崭,用到了某個(gè)函數(shù)的其他功能,而這個(gè)功能有bug的話瓦哎,那絕對(duì)是一件非常郁悶的事情砸喻。所以說,每編寫完一個(gè)函數(shù)之后蒋譬,都應(yīng)該對(duì)這個(gè)函數(shù)的方方面面進(jìn)行測(cè)試割岛,這樣的測(cè)試我們稱之為單元測(cè)試。傳統(tǒng)的編程方式犯助,進(jìn)行單元測(cè)試是一件很麻煩的事情癣漆,你要重新寫另外一個(gè)程序,在該程序中調(diào)用你需要測(cè)試的方法也切,并且仔細(xì)觀察運(yùn)行結(jié)果扑媚,看看是否有錯(cuò)。正因?yàn)槿绱寺闊├资眩猿绦騿T們編寫單元測(cè)試的熱情不是很高疆股。于是有一個(gè)牛人推出了單元測(cè)試包,大大簡(jiǎn)化了進(jìn)行單元測(cè)試所要做的工作倒槐,這就是JUnit4旬痹。本文簡(jiǎn)要介紹一下在Eclipse3.2中使用JUnit4進(jìn)行單元測(cè)試的方法。
1.2 單元測(cè)試JUnit4實(shí)踐
首先讨越,我們來一個(gè)傻瓜式速成教程两残,不要問為什么,F(xiàn)ollow Me把跨,先來體驗(yàn)一下單元測(cè)試的快感人弓!
- 第一步,首先新建一個(gè)項(xiàng)目叫JUnit_Test着逐,我們編寫一個(gè)Calculator類崔赌,這是一個(gè)能夠簡(jiǎn)單實(shí)現(xiàn)加減乘除、平方耸别、開方的計(jì)算器類健芭,然后對(duì)這些功能進(jìn)行單元測(cè)試。這個(gè)類并不是很完美秀姐,我們故意保留了一些Bug用于演示慈迈,這些Bug在注釋中都有說明。該類代碼如下:
package andycpp;
public class Calculator {
private static int result; // 靜態(tài)變量省有,用于存儲(chǔ)運(yùn)行結(jié)果
public void add(int n) {
result = result + n;
}
public void substract(int n) {
result = result - 1; //Bug: 正確的應(yīng)該是 result =result-n
}
public void multiply(int n) {
} // 此方法尚未寫好
public void divide(int n) {
result = result / n;
}
public void square(int n) {
result = n * n;
}
public void squareRoot(int n) {
for (; ;) ; //Bug : 死循環(huán)
}
public void clear() { // 將結(jié)果清零
result = 0;
}
public int getResult() {
return result;
}
}
- 第二步痒留,將JUnit4單元測(cè)試包引入這個(gè)項(xiàng)目:在該項(xiàng)目上點(diǎn)右鍵谴麦,點(diǎn)“屬性”,如圖:
在彈出的屬性窗口中狭瞎,首先在左邊選擇“Java Build Path”细移,然后到右上選擇“Libraries”標(biāo)簽搏予,之后在最右邊點(diǎn)擊“Add Library…”按鈕熊锭,如下圖所示:
然后在新彈出的對(duì)話框中選擇JUnit4并點(diǎn)擊確定,如上圖所示雪侥,JUnit4軟件包就被包含進(jìn)我們這個(gè)項(xiàng)目了碗殷。
- 第三步,生成JUnit測(cè)試框架:在Eclipse的Package Explorer中用右鍵點(diǎn)擊該類彈出菜單速缨,選擇“New à JUnit Test Case”锌妻。如下圖所示:
在彈出的對(duì)話框中,進(jìn)行相應(yīng)的選擇旬牲,如下圖所示:
點(diǎn)擊“下一步”后仿粹,系統(tǒng)會(huì)自動(dòng)列出你這個(gè)類中包含的方法,選擇你要進(jìn)行測(cè)試的方法原茅。此例中,我們僅對(duì)“加、減蔑祟、乘寞埠、除”四個(gè)方法進(jìn)行測(cè)試。如下圖所示:
之后系統(tǒng)會(huì)自動(dòng)生成一個(gè)新類CalculatorTest通贞,里面包含一些空的測(cè)試用例朗若。你只需要將這些測(cè)試用例稍作修改即可使用。完整的CalculatorTest代碼如下:
package andycpp;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
public class CalculatorTest {
private static Calculator calculator = new Calculator();
@Before
public void setUp() throws Exception {
calculator.clear();
}
@Test
public void testAdd() {
calculator.add(2);
calculator.add(3);
assertEquals(5, calculator.getResult());
}
@Test
public void testSubstract() {
calculator.add(10);
calculator.substract(2);
assertEquals(8, calculator.getResult());
}
@Ignore("Multiply() Not yet implemented")
@Test
public void testMultiply() {
}
@Test
public void testDivide() {
calculator.add(8);
calculator.divide(2);
assertEquals(4, calculator.getResult());
}
}
- 第四步昌罩,運(yùn)行測(cè)試代碼:按照上述代碼修改完畢后哭懈,我們?cè)贑alculatorTest類上點(diǎn)右鍵,選擇“Run As à JUnit Test”來運(yùn)行我們的測(cè)試茎用,如下圖所示:
運(yùn)行結(jié)果如下:
進(jìn)度條是紅顏色表示發(fā)現(xiàn)錯(cuò)誤遣总,具體的測(cè)試結(jié)果在進(jìn)度條上面有表示“共進(jìn)行了4個(gè)測(cè)試,其中1個(gè)測(cè)試被忽略绘搞,一個(gè)測(cè)試失敗”
至此彤避,我們已經(jīng)完整體驗(yàn)了在Eclipse中使用JUnit的方法。在接下來的文章中夯辖,我會(huì)詳細(xì)解釋測(cè)試代碼中的每一個(gè)細(xì)節(jié)琉预!
2. 中級(jí)篇
我們繼續(xù)對(duì)初級(jí)篇中的例子進(jìn)行分析。初級(jí)篇中我們使用Eclipse自動(dòng)生成了一個(gè)測(cè)試框架蒿褂,在這篇文章中圆米,我們來仔細(xì)分析一下這個(gè)測(cè)試框架中的每一個(gè)細(xì)節(jié)卒暂,知其然更要知其所以然,才能更加熟練地應(yīng)用JUnit4娄帖。
- 1 . 包含必要地Package
在測(cè)試類中用到了JUnit4框架也祠,自然要把相應(yīng)地Package包含進(jìn)來。最主要地一個(gè)Package就是org.junit.近速。把它包含進(jìn)來之后诈嘿,絕大部分功能就有了。還有一句話也非常地重要“import static org.junit.Assert.;”削葱,我們?cè)跍y(cè)試的時(shí)候使用的一系列assertEquals方法就來自這個(gè)包奖亚。大家注意一下,這是一個(gè)靜態(tài)包含(static)析砸,是JDK5中新增添的一個(gè)功能昔字。也就是說,assertEquals是Assert類中的一系列的靜態(tài)方法首繁,一般的使用方式是Assert. assertEquals()作郭,但是使用了靜態(tài)包含后,前面的類名就可以省略了弦疮,使用起來更加的方便夹攒。
- 2 . 測(cè)試類的聲明
大家注意到,我們的測(cè)試類是一個(gè)獨(dú)立的類挂捅,沒有任何父類芹助。測(cè)試類的名字也可以任意命名,沒有任何局限性闲先。所以我們不能通過類的聲明來判斷它是不是一個(gè)測(cè)試類状土,它與普通類的區(qū)別在于它內(nèi)部的方法的聲明,我們接著會(huì)講到伺糠。
- 3 .創(chuàng)建一個(gè)待測(cè)試的對(duì)象
你要測(cè)試哪個(gè)類蒙谓,那么你首先就要?jiǎng)?chuàng)建一個(gè)該類的對(duì)象。正如上一篇文章中的代碼:
private static Calculator calculator = new Calculator();
為了測(cè)試Calculator類训桶,我們必須創(chuàng)建一個(gè)calculator對(duì)象累驮。
- 4 .測(cè)試方法的聲明
在測(cè)試類中,并不是每一個(gè)方法都是用于測(cè)試的舵揭,你必須使用“標(biāo)注”來明確表明哪些是測(cè)試方法谤专。“標(biāo)注”也是JDK5的一個(gè)新特性午绳,用在此處非常恰當(dāng)置侍。我們可以看到,在某些方法的前有@Before、@Test蜡坊、@Ignore等字樣杠输,這些就是標(biāo)注,以一個(gè)“@”作為開頭秕衙。這些標(biāo)注都是JUnit4自定義的蠢甲,熟練掌握這些標(biāo)注的含義非常重要。
- 5 . 編寫一個(gè)簡(jiǎn)單的測(cè)試方法
首先据忘,你要在方法的前面使用@Test標(biāo)注鹦牛,以表明這是一個(gè)測(cè)試方法。對(duì)于方法的聲明也有如下要求:名字可以隨便取若河,沒有任何限制能岩,但是返回值必須為void寞宫,而且不能有任何參數(shù)萧福。如果違反這些規(guī)定,會(huì)在運(yùn)行時(shí)拋出一個(gè)異常辈赋。至于方法內(nèi)該寫些什么鲫忍,那就要看你需要測(cè)試些什么了。比如:
@Test
public void testAdd() {
calculator.add(2);
calculator.add(3);
assertEquals(5, calculator.getResult());
}
我們想測(cè)試一下“加法”功能時(shí)候正確钥屈,就在測(cè)試方法中調(diào)用幾次add函數(shù)悟民,初始值為0,先加2篷就,再加3射亏,我們期待的結(jié)果應(yīng)該是5。如果最終實(shí)際結(jié)果也是5竭业,則說明add方法是正確的智润,反之說明它是錯(cuò)的。assertEquals(5, calculator.getResult());就是來判斷期待結(jié)果和實(shí)際結(jié)果是否相等未辆,第一個(gè)參數(shù)填寫期待結(jié)果窟绷,第二個(gè)參數(shù)填寫實(shí)際結(jié)果,也就是通過計(jì)算得到的結(jié)果咐柜。這樣寫好之后兼蜈,JUnit會(huì)自動(dòng)進(jìn)行測(cè)試并把測(cè)試結(jié)果反饋給用戶。
- 6 .忽略測(cè)試某些尚未完成的方法
如果你在寫程序前做了很好的規(guī)劃拙友,那么哪些方法是什么功能都應(yīng)該實(shí)現(xiàn)定下來为狸。因此,即使該方法尚未完成遗契,他的具體功能也是確定的辐棒,這也就意味著你可以為他編寫測(cè)試用例。但是,如果你已經(jīng)把該方法的測(cè)試用例寫完涉瘾,但該方法尚未完成知态,那么測(cè)試的時(shí)候一定是“失敗”。這種失敗和真正的失敗是有區(qū)別的立叛,因此JUnit提供了一種方法來區(qū)別他們负敏,那就是在這種測(cè)試函數(shù)的前面加上@Ignore標(biāo)注,這個(gè)標(biāo)注的含義就是“某些方法尚未完成秘蛇,暫不參與此次測(cè)試”其做。這樣的話測(cè)試結(jié)果就會(huì)提示你有幾個(gè)測(cè)試被忽略,而不是失敗赁还。一旦你完成了相應(yīng)函數(shù)妖泄,只需要把@Ignore標(biāo)注刪去,就可以進(jìn)行正常的測(cè)試艘策。
- 7 . Fixture(暫且翻譯為“固定代碼段”)
Fixture的含義就是“在某些階段必然被調(diào)用的代碼”蹈胡。比如我們上面的測(cè)試,由于只聲明了一個(gè)Calculator對(duì)象朋蔫,他的初始值是0罚渐,但是測(cè)試完加法操作后,他的值就不是0了驯妄;接下來測(cè)試減法操作荷并,就必然要考慮上次加法操作的結(jié)果。這絕對(duì)是一個(gè)很糟糕的設(shè)計(jì)青扔!我們非常希望每一個(gè)測(cè)試都是獨(dú)立的源织,相互之間沒有任何耦合度。因此微猖,我們就很有必要在執(zhí)行每一個(gè)測(cè)試之前谈息,對(duì)Calculator對(duì)象進(jìn)行一個(gè)“復(fù)原”操作,以消除其他測(cè)試造成的影響励两。因此黎茎,“在任何一個(gè)測(cè)試執(zhí)行之前必須執(zhí)行的代碼”就是一個(gè)Fixture,我們用@Before來標(biāo)注它当悔,如前面例子所示:
@Before
public void setUp() throws Exception {
calculator.clear();
}
這里不在需要@Test標(biāo)注傅瞻,因?yàn)檫@不是一個(gè)test,而是一個(gè)Fixture盲憎。同理嗅骄,如果“在任何測(cè)試執(zhí)行之后需要進(jìn)行的收尾工作”也是一個(gè)Fixture,使用@After來標(biāo)注饼疙。由于本例比較簡(jiǎn)單溺森,沒有用到此功能。
JUnit4的一些基本知識(shí)就介紹到此,還有一些更靈活的用法放在本系列的高級(jí)篇中給大家介紹屏积!
3. 高級(jí)篇
通過前 2 篇文章医窿,您一定對(duì) JUnit 有了一個(gè)基本的了解,下面我們來探討一下 JUnit4 中一些高級(jí)特性炊林。
一姥卢、 高級(jí) Fixture
上一篇文章中我們介紹了兩個(gè) Fixture 標(biāo)注,分別是 @Before 和 @After 渣聚,我們來看看他們是否適合完成如下功能:有一個(gè)類是負(fù)責(zé)對(duì)大文件(超過 500 兆)進(jìn)行讀寫独榴,他的每一個(gè)方法都是對(duì)文件進(jìn)行操作。換句話說奕枝,在調(diào)用每一個(gè)方法之前棺榔,我們都要打開一個(gè)大文件并讀入文件內(nèi)容,這絕對(duì)是一個(gè)非常耗費(fèi)時(shí)間的操作隘道。如果我們使用 @Before 和 @After 症歇,那么每次測(cè)試都要讀取一次文件,效率及其低下薄声。這里我們所希望的是在所有測(cè)試一開始讀一次文件当船,所有測(cè)試結(jié)束之后釋放文件,而不是每次測(cè)試都讀文件默辨。 JUnit 的作者顯然也考慮到了這個(gè)問題,它給出了 @BeforeClass 和 @AfterClass 兩個(gè) Fixture 來幫我們實(shí)現(xiàn)這個(gè)功能苍息。從名字上就可以看出缩幸,用這兩個(gè) Fixture 標(biāo)注的函數(shù),只在測(cè)試用例初始化時(shí)執(zhí)行 @BeforeClass 方法竞思,當(dāng)所有測(cè)試執(zhí)行完畢之后表谊,執(zhí)行 @AfterClass 進(jìn)行收尾工作。在這里要注意一下盖喷,每個(gè)測(cè)試類只能有一個(gè)方法被標(biāo)注為 @BeforeClass 或 @AfterClass 爆办,并且該方法必須是 Public 和 Static 的。
二课梳、 限時(shí)測(cè)試
還記得我在初級(jí)篇中給出的例子嗎距辆,那個(gè)求平方根的函數(shù)有 Bug ,是個(gè)死循環(huán):
public void squareRoot( int n) {
for (; ;) ; // Bug : 死循環(huán)
}
如果測(cè)試的時(shí)候遇到死循環(huán)暮刃,你的臉上絕對(duì)不會(huì)露出笑容跨算。因此,對(duì)于那些邏輯很復(fù)雜椭懊,循環(huán)嵌套比較深的程序诸蚕,很有可能出現(xiàn)死循環(huán),因此一定要采取一些預(yù)防措施。限時(shí)測(cè)試是一個(gè)很好的解決方案背犯。我們給這些測(cè)試函數(shù)設(shè)定一個(gè)執(zhí)行時(shí)間坏瘩,超過了這個(gè)時(shí)間,他們就會(huì)被系統(tǒng)強(qiáng)行終止漠魏,并且系統(tǒng)還會(huì)向你匯報(bào)該函數(shù)結(jié)束的原因是因?yàn)槌瑫r(shí)桑腮,這樣你就可以發(fā)現(xiàn)這些 Bug 了。要實(shí)現(xiàn)這一功能蛉幸,只需要給 @Test 標(biāo)注加一個(gè)參數(shù)即可破讨,代碼如下:
@Test(timeout = 1000 )
public void squareRoot() {
calculator.squareRoot( 4 );
assertEquals( 2 , calculator.getResult());
}
Timeout 參數(shù)表明了你要設(shè)定的時(shí)間,單位為毫秒奕纫,因此 1000 就代表 1 秒提陶。
三、 測(cè)試異常
JAVA 中的異常處理也是一個(gè)重點(diǎn)匹层,因此你經(jīng)常會(huì)編寫一些需要拋出異常的函數(shù)隙笆。那么,如果你覺得一個(gè)函數(shù)應(yīng)該拋出異常升筏,但是它沒拋出撑柔,這算不算 Bug 呢?這當(dāng)然是 Bug 您访,并 JUnit 也考慮到了這一點(diǎn)铅忿,來幫助我們找到這種 Bug 。例如灵汪,我們寫的計(jì)算器類有除法功能檀训,如果除數(shù)是一個(gè) 0 ,那么必然要拋出“除 0 異诚硌裕”峻凫。因此,我們很有必要對(duì)這些進(jìn)行測(cè)試览露。代碼如下:
@Test(expected = ArithmeticException. class )
public void divideByZero() {
calculator.divide( 0 );
}
如上述代碼所示荧琼,我們需要使用
@Test
標(biāo)注的expected
屬性,將我們要檢驗(yàn)的
異常傳遞給他差牛,這樣JUnit
框架就能自動(dòng)幫我們檢測(cè)是否拋出了我們指定的異常命锄。
四、 Runner ( 運(yùn)行器 )
大家有沒有想過這個(gè)問題多糠,當(dāng)你把測(cè)試代碼提交給 JUnit 框架后累舷,框架如何來運(yùn)行你的代碼呢?答案就是—— Runner 夹孔。在 JUnit 中有很多個(gè) Runner 被盈,他們負(fù)責(zé)調(diào)用你的測(cè)試代碼析孽,每一個(gè) Runner 都有各自的特殊功能,你要根據(jù)需要選擇不同的 Runner 來運(yùn)行你的測(cè)試代碼只怎⊥嗨玻可能你會(huì)覺得奇怪,前面我們寫了那么多測(cè)試身堡,并沒有明確指定一個(gè) Runner 暗擞取?這是因?yàn)?JUnit 中有一個(gè)默認(rèn) Runner 贴谎,如果你沒有指定汞扎,那么系統(tǒng)自動(dòng)使用默認(rèn) Runner 來運(yùn)行你的代碼。換句話說擅这,下面兩段代碼含義是完全一樣的:
import org.junit.internal.runners.TestClassRunner;
import org.junit.runner.RunWith;
// 使用了系統(tǒng)默認(rèn)的TestClassRunner澈魄,與下面代碼完全一樣
public class CalculatorTest {
...
}
@RunWith(TestClassRunner. class )
public class CalculatorTest {
...
}
從上述例子可以看出,要想指定一個(gè) Runner 仲翎,需要使用 @RunWith 標(biāo)注痹扇,并且把你所指定的 Runner 作為參數(shù)傳遞給它。另外一個(gè)要注意的是溯香, @RunWith 是用來修飾類的鲫构,而不是用來修飾函數(shù)的。只要對(duì)一個(gè)類指定了 Runner 玫坛,那么這個(gè)類中的所有函數(shù)都被這個(gè) Runner 來調(diào)用结笨。最后,不要忘了包含相應(yīng)的 Package 哦昂秃,上面的例子對(duì)這一點(diǎn)寫的很清楚了禀梳。接下來,我會(huì)向你們展示其他 Runner 的特有功能肠骆。
五、 參數(shù)化測(cè)試
你可能遇到過這樣的函數(shù)塞耕,它的參數(shù)有許多特殊值蚀腿,或者說他的參數(shù)分為很多個(gè)區(qū)域。比如扫外,一個(gè)對(duì)考試分?jǐn)?shù)進(jìn)行評(píng)價(jià)的函數(shù)莉钙,返回值分別為“優(yōu)秀,良好筛谚,一般磁玉,及格,不及格”驾讲,因此你在編寫測(cè)試的時(shí)候蚊伞,至少要寫 5 個(gè)測(cè)試席赂,把這 5 中情況都包含了,這確實(shí)是一件很麻煩的事情时迫。我們還使用我們先前的例子颅停,測(cè)試一下“計(jì)算一個(gè)數(shù)的平方”這個(gè)函數(shù),暫且分三類:正數(shù)掠拳、 0 癞揉、負(fù)數(shù)。測(cè)試代碼如下:
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert. * ;
public class AdvancedTest {
private static Calculator calculator = new Calculator();
@Before
public void clearCalculator() {
calculator.clear();
}
@Test
public void square1() {
calculator.square( 2 );
assertEquals( 4 , calculator.getResult());
}
@Test
public void square2() {
calculator.square( 0 );
assertEquals( 0 , calculator.getResult());
}
@Test
public void square3() {
calculator.square( - 3 );
assertEquals( 9 , calculator.getResult());
}
}
為了簡(jiǎn)化類似的測(cè)試溺欧, JUnit4 提出了“參數(shù)化測(cè)試”的概念喊熟,只寫一個(gè)測(cè)試函數(shù),把這若干種情況作為參數(shù)傳遞進(jìn)去姐刁,一次性的完成測(cè)試芥牌。代碼如下:
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import java.util.Arrays;
import java.util.Collection;
@RunWith(Parameterized. class )
public class SquareTest {
private static Calculator calculator = new Calculator();
private int param;
private int result;
@Parameters
public static Collection data() {
return Arrays.asList( new Object[][] {
{ 2 , 4 } ,
{ 0 , 0 } ,
{- 3 , 9 } ,
} );
}
// 構(gòu)造函數(shù),對(duì)變量進(jìn)行初始化
public SquareTest( int param, int result) {
this .param = param;
this .result = result;
}
@Test
public void square() {
calculator.square(param);
assertEquals(result, calculator.getResult());
}
}
下面我們對(duì)上述代碼進(jìn)行分析龙填。首先胳泉,你要為這種測(cè)試專門生成一個(gè)新的類,而不能與其他測(cè)試共用同一個(gè)類岩遗,此例中我們定義了一個(gè)SquareTest類扇商。然后,你要為這個(gè)類指定一個(gè)Runner宿礁,而不能使用默認(rèn)的Runner了案铺,因?yàn)樘厥獾墓δ芤锰厥獾腞unner嘛。@RunWith(Parameterized.class)這條語句就是為這個(gè)類指定了一個(gè)ParameterizedRunner梆靖。第二步控汉,定義一個(gè)待測(cè)試的類,并且定義兩個(gè)變量返吻,一個(gè)用于存放參數(shù)姑子,一個(gè)用于存放期待的結(jié)果。接下來测僵,定義測(cè)試數(shù)據(jù)的集合街佑,也就是上述的data()方法,該方法可以任意命名捍靠,但是必須使用@Parameters標(biāo)注進(jìn)行修飾沐旨。這個(gè)方法的框架就不予解釋了,大家只需要注意其中的數(shù)據(jù)榨婆,是一個(gè)二維數(shù)組磁携,數(shù)據(jù)兩兩一組,每組中的這兩個(gè)數(shù)據(jù)良风,一個(gè)是參數(shù)谊迄,一個(gè)是你預(yù)期的結(jié)果闷供。比如我們的第一組{2, 4},2就是參數(shù)鳞上,4就是預(yù)期的結(jié)果这吻。這兩個(gè)數(shù)據(jù)的順序無所謂,誰前誰后都可以篙议。之后是構(gòu)造函數(shù)唾糯,其功能就是對(duì)先前定義的兩個(gè)參數(shù)進(jìn)行初始化。 在這里你可要注意一下參數(shù)的順序了鬼贱,要和上面的數(shù)據(jù)集合的順序保持一致移怯。如果前面的順序是{參數(shù),期待的結(jié)果}这难,那么你構(gòu)造函數(shù)的順序也要是“構(gòu)造函數(shù)(參數(shù)舟误, 期待的結(jié)果)”,反之亦然姻乓。最后就是寫一個(gè)簡(jiǎn)單的測(cè)試?yán)饲兑纾颓懊娼榻B過的寫法完全一樣,在此就不多說蹋岩。
六赖草、 打包測(cè)試
通過前面的介紹我們可以感覺到,在一個(gè)項(xiàng)目中剪个,只寫一個(gè)測(cè)試類是不可能的秧骑,我們會(huì)寫出很多很多個(gè)測(cè)試類】勰遥可是這些測(cè)試類必須一個(gè)一個(gè)的執(zhí)行乎折,也是比較麻煩的事情。鑒于此侵歇, JUnit 為我們提供了打包測(cè)試的功能骂澄,將所有需要運(yùn)行的測(cè)試類集中起來,一次性的運(yùn)行完畢惕虑,大大的方便了我們的測(cè)試工作酗洒。具體代碼如下:
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite. class )
@Suite.SuiteClasses( {
CalculatorTest. class ,
SquareTest. class
} )
public class AllCalculatorTests {
}
大家可以看到,這個(gè)功能也需要使用一個(gè)特殊的 Runner 枷遂,因此我們需要向 @RunWith 標(biāo)注傳遞一個(gè)參數(shù) Suite.class 。同時(shí)棋嘲,我們還需要另外一個(gè)標(biāo)注 @Suite.SuiteClasses 酒唉,來表明這個(gè)類是一個(gè)打包測(cè)試類。我們把需要打包的類作為參數(shù)傳遞給該標(biāo)注就可以了沸移。有了這兩個(gè)標(biāo)注之后痪伦,就已經(jīng)完整的表達(dá)了所有的含義侄榴,因此下面的類已經(jīng)無關(guān)緊要,隨便起一個(gè)類名网沾,內(nèi)容全部為空既可癞蚕。
至此,本系列文章全部結(jié)束辉哥,希望能夠?qū)Υ蠹沂褂?JUnit4 有所幫助桦山。
標(biāo)注:
這篇,是我從其它博客上看到的三篇文章整理成的一篇醋旦,希望為將來的項(xiàng)目進(jìn)行JUnit4測(cè)試提供幫助恒水。