JUnit之TestCase和TestSuite詳解

Android Studio下單元測試的本質(zhì)其實(shí)是根據(jù)通過書寫JAVA測試代碼放航,通過模擬用戶調(diào)用相應(yīng)的方法置鼻,或者使用者按下相應(yīng)的按鍵來驗(yàn)證我們的代碼的邏輯是否能達(dá)到預(yù)期的要求,如果所有的用例都能通過丹壕,則證明我們的邏輯滿足要求庆械,否則,可以通過fail()函數(shù)(或使用Assert)進(jìn)行輸出錯誤信息菌赖。

在進(jìn)行測試前我們首先需要了解一下幾個基本的概念:TestCase缭乘,TestSuite:

(圖1)

如圖1所示,TestSuite和TestCase都是繼承自Test接口琉用,同時,TestSuite的建立和使用依賴于TestCase實(shí)例邑时,TestCase繼承自Assert類奴紧,因此TestCase中可以直接使用Assert中的相關(guān)方法,Assert類提供了幾個常用的判斷方法,Assert的類圖可以參照圖2:

(圖2)

TestCase:

在進(jìn)行單元測試的時候晶丘,在JUNIT4之前黍氮,我們需要測試的代碼所在的類一般都需要直接或者間接繼承自TestCase,對于我們創(chuàng)建的這個TestCase的子類浅浮,我們需要注意在我們這個類的測試流程沫浆,假設(shè)我們創(chuàng)建的TestCase子類中有兩個測試用例testMethod1和testMethod2,則執(zhí)行順序可以如圖3所示:

(圖3)

對于我們類中的兩個測試用例testMethod1和testMethod2滚秩,都會分別創(chuàng)建一個新的TestCase子類對象专执,并引起TestCase中的setUp和tearDown函數(shù)分別執(zhí)行一遍,因此郁油,在進(jìn)行單元測試的過程中本股,我們可以在setUp當(dāng)中進(jìn)行一些初始化操作(如類的某些屬性的賦值操作),在tearDown中進(jìn)行一些掃尾工作(如類中某些對象所持有資源的釋放)桐腌。

一個簡單的Demo:

import junit.framework.TestCase;

public class TestDemo extends TestCase{

@Override

protected void setUp() throws Exception {

// TODO Auto-generated method stub

super.setUp();

System.out.println("setUp , hashCode = "+hashCode());

}

@Override

protected void tearDown() throws Exception {

// TODO Auto-generated method stub

super.tearDown();

System.out.println("tearDown,hashCode = "+hashCode());

}

public void testMethod1(){

System.out.println("testMethod1 , hashCode = "+hashCode());

}

public void testMethod2(){

System.out.println("testMethod2 , hashCode = "+hashCode());

}

}

運(yùn)行結(jié)果拄显,如圖4所示:

(圖4)

有兩個test函數(shù),testMethod1和testMethod2案站,在生命周期的開始函數(shù)setUp以及結(jié)尾函數(shù)tearDown中分別產(chǎn)生了兩次不同的hashCode躬审,根據(jù)Java語言中HashCode的概念我們可以知道這分別導(dǎo)致了我們的TestDemo類型的對象創(chuàng)建了兩次。因此如果測試的case增多,我們的TestDemo對象也會創(chuàng)建和case相同的個數(shù)盒件。

對于測試用例testMethod1和testMethod2的函數(shù)聲明,在我們書寫用例函數(shù)的時候需要注意他們有一個共同的特點(diǎn):

1).訪問權(quán)限都是public舱禽;

2).返回類型都是void;

3).沒有參數(shù)炒刁;

4).方法名以“test”開頭。

在使用單元測試的時候必須注意用例方法的生命格式誊稚,否則該用例將不會被執(zhí)行的到翔始。

TestSuite:

對于suite這個英文單詞,從字面上可以理解為組合或者集合的意思里伯,再加上通過圖1城瞎,我們發(fā)現(xiàn)TestSuite和TestCase都是實(shí)現(xiàn)自Test接口,這很容易讓我們想起JAVA設(shè)計模式中的合成模式的概念:即TestSuite可以認(rèn)為合成模式中的組疾瓮,是一組TestCase對象的集合脖镀;而TestCase對象時這個合成模式中的葉子對象,并且狼电,這些TestCase對象(葉子對象)和TestSuite(組對象)擁有共同的行為(run方法)蜒灰;這樣,可以保證當(dāng)用戶調(diào)用組對象TestSuite的run方法的時候肩碟,也會調(diào)用到TestCase對象的run方法强窖。而事實(shí)上也確實(shí)是這樣,在使用JUnit3執(zhí)行測試的過程中削祈,會首先創(chuàng)建TestSuite對象翅溺,在TestSuite對象的構(gòu)造方法中,會掃描TestCase子類的所有方法髓抑,并調(diào)用addTestMethod方法咙崎,在該方法中調(diào)用isPublicTestMethod方法判斷是否是待測的方法,若是會調(diào)用createTest方法启昧,創(chuàng)建一個Test對象叙凡,并調(diào)用addTest方法加入到自己的集合中去,因此執(zhí)行過程中的TestCase子類都會以具體的test方法個數(shù)創(chuàng)建自身實(shí)例的個數(shù)密末,并加入到TestSuite中握爷,TestSuite的相對詳細(xì)的類圖如圖5所示:

(圖5)

一個簡單的例子了解一下TestSuite:

import junit.framework.Test;

import junit.framework.TestCase;

import junit.framework.TestSuite;

public class TestSuiteDemo extends TestSuite{

public static Test suite(){

//創(chuàng)建TestSuite對象

TestSuite suite = new TestSuite();

//為TestSuite添加一個測試用例集合,參數(shù)為:ClasstestClass

//通過參數(shù)可以知道严里,其實(shí)該參數(shù)就是TestCase的子類

suite.addTestSuite(TestDemo.class);

//創(chuàng)建具體的測試用例

Test test = TestSuite.createTest(TestDemo.class, "testMethod1");

//添加一個具體的測試用例

suite.addTest(test);

return suite;

}

}

執(zhí)行結(jié)果如圖6:

(圖6)

通過代碼和運(yùn)行結(jié)果新啼,我們可以看出testMethod1執(zhí)行了兩次而testMethod2只執(zhí)行了一次,通過分析上述代碼得出testMethod1執(zhí)行兩次的原因是:第一次是在addTestSuite的時候?qū)⑵渥鳛橐粋€測試用例傳入到TestSuite中刹碾,第二次是通過addTest方法將用例加入到TestSuite中燥撞,因此在執(zhí)行的時候?qū)⑵鋱?zhí)行了兩遍,通過比較hashCode得出總共創(chuàng)建了三個TestCase對象的結(jié)論。

通過上述代碼物舒,我們需要強(qiáng)調(diào)一下色洞,如果我們想一次執(zhí)行一組TestCase實(shí)現(xiàn)類的測試,這個時候可以自定義TestSuite對象冠胯,將需要測試的TestCase實(shí)現(xiàn)類加入到TestSuite中去火诸。我們需要了解TestSuite如何使用,其實(shí)TestSuite的使用也很簡單荠察,在TestSuite的使用的時候置蜀,我們必須在TestSuite的實(shí)現(xiàn)類中,自定義suite方法悉盆,由于suite方法會通過反射調(diào)用,反射調(diào)用代碼如下:

public static Test testFromSuiteMethod(Classklass) throws Throwable {

Method suiteMethod= null;

Test suite= null;

try {

suiteMethod= klass.getMethod("suite");

if (! Modifier.isStatic(suiteMethod.getModifiers())) {

throw new Exception(klass.getName() + ".suite() must be static");

}

suite= (Test) suiteMethod.invoke(null); // static method

} catch (InvocationTargetException e) {

throw e.getCause();

}

return suite;

}

所以suite方法命名規(guī)則如下:

1).必須以“suite”方法命名焕盟;

2).suite方法的訪問修飾權(quán)限必須為static秋秤;

3).suite方法必須為靜態(tài)方法;

4).suite方法必須沒有參數(shù)脚翘。

總結(jié):

TestCase和TestSuite類是JUNIT中比較重要的兩個類航缀,TestCase和TestSuite可以認(rèn)為是JAVA的合成設(shè)計模式在單元測試中的應(yīng)用,其實(shí)即便我們沒有自己聲明和創(chuàng)建TestSuite的子類堰怨,而且運(yùn)行的TestCase子類的過程中也會創(chuàng)建TestSuite類芥玉,并將要執(zhí)行的TestCase子類的實(shí)例對象添加到TestSuite中去執(zhí)行,其執(zhí)行過程可以如圖7所示:

(圖7)

在選擇JUnit執(zhí)行引擎的時候备图,便創(chuàng)建了TestSuite對象灿巧,并通過上面介紹TestSuite介紹過的addTestMethod,creatTest揽涮,addTest方法抠藕,將要測的TestCase類中的所有測試用例給掃描出來,并添加到待測列表中去蒋困。在執(zhí)行JUnit測試引擎的run方法時會調(diào)用TestSuite的的run方法盾似,TestSuite在執(zhí)行自身run方法時會遍歷所有TestCase對象的run方法,同一個TestCase子類的run方法會根據(jù)自身所包含的測試用例個數(shù)被執(zhí)行相應(yīng)的次數(shù)雪标。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末零院,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子村刨,更是在濱河造成了極大的恐慌告抄,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嵌牺,死亡現(xiàn)場離奇詭異打洼,居然都是意外死亡龄糊,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門募疮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來炫惩,“玉大人,你說我怎么就攤上這事阿浓」畋兀” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵搔扁,是天一觀的道長。 經(jīng)常有香客問我蟋字,道長稿蹲,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任鹊奖,我火速辦了婚禮苛聘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘忠聚。我一直安慰自己设哗,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布两蟀。 她就那樣靜靜地躺著网梢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪赂毯。 梳的紋絲不亂的頭發(fā)上战虏,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天,我揣著相機(jī)與錄音党涕,去河邊找鬼烦感。 笑死,一個胖子當(dāng)著我的面吹牛膛堤,可吹牛的內(nèi)容都是我干的手趣。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼肥荔,長吁一口氣:“原來是場噩夢啊……” “哼绿渣!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起燕耿,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤怯晕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后缸棵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體舟茶,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了吧凉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片隧出。...
    茶點(diǎn)故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖阀捅,靈堂內(nèi)的尸體忽然破棺而出胀瞪,到底是詐尸還是另有隱情,我是刑警寧澤饲鄙,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布凄诞,位于F島的核電站,受9級特大地震影響忍级,放射性物質(zhì)發(fā)生泄漏帆谍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一轴咱、第九天 我趴在偏房一處隱蔽的房頂上張望汛蝙。 院中可真熱鬧,春花似錦朴肺、人聲如沸窖剑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽西土。三九已至,卻和暖如春鞍盗,著一層夾襖步出監(jiān)牢的瞬間翠储,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工橡疼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留援所,地道東北人。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓欣除,卻偏偏與公主長得像住拭,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子历帚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法滔岳,類相關(guān)的語法,內(nèi)部類的語法挽牢,繼承相關(guān)的語法谱煤,異常的語法,線程的語...
    子非魚_t_閱讀 31,631評論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理禽拔,服務(wù)發(fā)現(xiàn)刘离,斷路器室叉,智...
    卡卡羅2017閱讀 134,656評論 18 139
  • Startup 單元測試的核心價值在于兩點(diǎn): 更加精確地定義某段代碼的作用,從而使代碼的耦合性更低 避免程序員寫出...
    wuwenxiang閱讀 10,097評論 1 27
  • 不知道大家有沒有過這種感覺踪旷,喜歡著一個明明不愛自己的人,也知道彼此不可能豁辉,卻依然愛著令野。 如果沒有的話,那下面便可不...
    流浪漢9595閱讀 1,759評論 0 1