JUnit之TestCase和TestSuite詳解

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

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

(圖1)

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

(圖2)

TestCase:

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

(圖3)

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

一個(gè)簡(jiǎ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)

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

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

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

2).返回類型都是void;

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

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

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

TestSuite:

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

(圖5)

一個(gè)簡(jiǎn)單的例子了解一下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對(duì)象

TestSuite suite = new TestSuite();

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

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

suite.addTestSuite(TestDemo.class);

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

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

//添加一個(gè)具體的測(cè)試用例

suite.addTest(test);

return suite;

}

}

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

(圖6)

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

通過上述代碼,我們需要強(qiáng)調(diào)一下,如果我們想一次執(zhí)行一組TestCase實(shí)現(xiàn)類的測(cè)試,這個(gè)時(shí)候可以自定義TestSuite對(duì)象,將需要測(cè)試的TestCase實(shí)現(xiàn)類加入到TestSuite中去。我們需要了解TestSuite如何使用,其實(shí)TestSuite的使用也很簡(jiǎn)單,在TestSuite的使用的時(shí)候,我們必須在TestSuite的實(shí)現(xiàn)類中,自定義suite方法,由于suite方法會(huì)通過反射調(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中比較重要的兩個(gè)類,TestCase和TestSuite可以認(rèn)為是JAVA的合成設(shè)計(jì)模式在單元測(cè)試中的應(yīng)用,其實(shí)即便我們沒有自己聲明和創(chuàng)建TestSuite的子類,而且運(yùn)行的TestCase子類的過程中也會(huì)創(chuàng)建TestSuite類,并將要執(zhí)行的TestCase子類的實(shí)例對(duì)象添加到TestSuite中去執(zhí)行,其執(zhí)行過程可以如圖7所示:

(圖7)

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容