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

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

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

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

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

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

       Constructor constructor;

       try {

              constructor= getTestConstructor(theClass);
       ……

       Object test;

       try {

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


              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});

              }

       ……
 

       //返回這個對象


       return (Test) test;

}

 

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

protected void runTest() throws Throwable {

       //fName是testcase對象所擁有的那個方法的名稱

       assertNotNull(fName);


       Method runMethod= null;

       try {

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


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

       }


       ……
 

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

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

       }


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

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

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

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

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

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

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