您的位置:軟件測(cè)試 > 開源軟件測(cè)試 > 開源單元測(cè)試工具 > junit
JUnit源碼分析
作者:網(wǎng)絡(luò)轉(zhuǎn)載 發(fā)布時(shí)間:[ 2013/1/18 13:59:32 ] 推薦標(biāo)簽:

從這個(gè)main方法入口,首先JUnit將要分析命令行的參數(shù),然后將檢查測(cè)試類是否包含符合標(biāo)準(zhǔn)的suite方法,如果有將執(zhí)行方法中的內(nèi)容(見圖中0、1部分);如果沒有找到將自動(dòng)生成一個(gè)TestSuite,這樣跳過了圖中的0部分,并將測(cè)試用例類作為參數(shù)傳入。

上面得到了一個(gè)TestSuite類型的對(duì)象,現(xiàn)在可以運(yùn)行測(cè)試了,不過在運(yùn)行前要先加載TestResult和TestListener的對(duì)象,用來(lái)監(jiān)聽和記錄測(cè)試結(jié)果信息。剩下的在圖中可以很容易的看懂了,你可以參照源碼瀏覽一遍。

這里提出我的一點(diǎn)疑問。注意到JUnit實(shí)踐中提示將測(cè)試類中每個(gè)測(cè)試方法公用的初始化步驟放到setup方法中。這似乎會(huì)給你一種錯(cuò)覺,那是你會(huì)認(rèn)為setup與tearDown中的語(yǔ)句對(duì)于一個(gè)測(cè)試類中的所有測(cè)試方法只會(huì)運(yùn)行一次。但是實(shí)際上JUnit在實(shí)現(xiàn)上卻出乎意料,setup對(duì)于測(cè)試類中的每個(gè)測(cè)試方法都回運(yùn)行一遍。意思是說,你把公用的初始化代碼放到setup方法中僅僅是在代碼結(jié)構(gòu)上實(shí)現(xiàn)了重用,而沒有起到任何優(yōu)化系統(tǒng)的作用。比如你在setUp中初始化數(shù)據(jù)庫(kù)連接,那么這個(gè)過程將被執(zhí)行不只一次,這可有點(diǎn)……。我們來(lái)看下代碼:

//theClass為得到的TestCase類,name為此類其中的一個(gè)方法

static public Test createTest(Class theClass, String name) {

       Constructor constructor;

       try {

              constructor= getTestConstructor(theClass);
       ……

       Object test;

       try {

//以下內(nèi)容為獲得一個(gè)TestCase對(duì)象,并將方法名稱傳入這個(gè)對(duì)象


              if (constructor.getParameterTypes().length == 0) {

                     test= constructor.newInstance(new Object[0]);

                    if (test instanceof TestCase)

                            ((TestCase) test).setName(name);

              } else {

                     test= constructor.newInstance(new Object[]{name});

              }

       ……
 

       //返回這個(gè)對(duì)象


       return (Test) test;

}

 

再看下運(yùn)行處的代碼,下面的方法是運(yùn)行在setUp和tearDown中間的

protected void runTest() throws Throwable {

       //fName是testcase對(duì)象所擁有的那個(gè)方法的名稱

       assertNotNull(fName);


       Method runMethod= null;

       try {

              //根據(jù)方法名由反射得到方法


              runMethod= getClass().getMethod(fName, null);

       }


       ……
 

              //執(zhí)行測(cè)試方法

              runMethod.invoke(this, new Class[0]);
……

       }


這樣每執(zhí)行一個(gè)測(cè)試方法要運(yùn)行一遍setUp和tearDown方法,大概是這樣一個(gè)過程:

恩……,也許這是為了兼容老的版本,也許是……。還好,JUnit提供了一個(gè)補(bǔ)救的擴(kuò)展類,那是我們上面提到的TestSetup,在這里類里面真正的實(shí)現(xiàn)了setUp、tearDown方法的提取使用。你在使用的時(shí)候,通過繼承來(lái)實(shí)現(xiàn)自己的setUp、tearDown方法,并使用裝飾模式獨(dú)有的調(diào)用方式來(lái)使用它可以了。

在閱讀的過程中,代碼風(fēng)格上給我明顯的感覺是,代碼基本上全多做到了細(xì)化,將每個(gè)功能點(diǎn)單獨(dú)提取到一個(gè)方法中,這樣提高了代碼的可復(fù)用性?墒窃陂喿x的時(shí)候,在方法間頻繁的跳躍,實(shí)在不是件好事,如果沒有IDE的幫助,我非要暈掉不可。

因此我認(rèn)為在提高代碼重用上還是要堅(jiān)持這樣的一條原則:到必要的時(shí)候再下手。是說,在你剛開始寫代碼的時(shí)候不要考慮什么重用和擴(kuò)展,只有當(dāng)你真正需要復(fù)用某段代碼或者擴(kuò)展系統(tǒng)時(shí),在動(dòng)手吧(記得在某位牛人的書上是這么來(lái)比喻的:讓第一顆子彈打中你)。

JUnit中使用的是老版本java collection,這大概是因?yàn)镴Unit初版本出現(xiàn)的時(shí)候還沒有新版collection推出。這種代碼不應(yīng)該出現(xiàn)在我們現(xiàn)在編寫的代碼中了,請(qǐng)注意。

好了,基本上分析完了JUnit的代碼,不知道你學(xué)到了什么。希望本文能夠起到拋磚引玉的作用。

上一頁(yè)123下一頁(yè)
軟件測(cè)試工具 | 聯(lián)系我們 | 投訴建議 | 誠(chéng)聘英才 | 申請(qǐng)使用列表 | 網(wǎng)站地圖
滬ICP備07036474 2003-2017 版權(quán)所有 上海澤眾軟件科技有限公司 Shanghai ZeZhong Software Co.,Ltd