下圖是根據源代碼分析出來的framework包中各個關鍵類之間的關系
Assert類提供了JUnit使用的一整套的斷言,這套斷言都被TestCase繼承下來,Assert也變成了透明的。
Test接口是為了統一TestCase和TestSuite的類型;
TestCase里面提供了運行單元測試類的方法;
TestSuite中則提供了加載單元測試類,檢驗測試類格式等等的方法。
TestResult故名思意是提供存放測試結果的地方,但是在JUnit中它還帶有一點控制器的功能。
TestListener接口抽象了所有測試監聽者的行為,他包括添加錯誤和失敗的方法,開始測試和結束測試的方法。在JUnit框架中有兩個類實現了這個接口,一個負責結果打印的ResultPrinter類,一個是所有TestRunner的基礎類BaseTestRunner類(這兩個類都不在framework包中)。
1.2 extentions包中類設計分析
在上面我們已經提到了junit.extentions包中的內容TestSetup。來看看整個包的結構吧。
先簡要的介紹下包中各個類的功能。
ActiveTestSuite對TestSuite進行了改進,使得每個test運行在一個單獨的線程里面,并且只到所有的線程都結束了才會結束整個測試。
ExceptionTestCase是對TestCase進行的改進,可以方便的判斷測試類是否拋出了期望的異常。
剩下的三個類,使用了裝飾模式來設計的。其中TestDecorator為具體裝飾類制定好了使用規則,RepeatedTest和TestSetup則是具體實現的裝飾類。
那為什么extentions包中ActiveTestSuite和ExceptionTestCase沒有使用裝飾模式呢?原因在于裝飾模式在結構上要求存在類似于組合模式的遞歸。而對于已有的TestCase和TestSuite來說,直接繼承它們要比構建一個新的遞歸結構要來得快得多而且簡單;并且這些增強功能都只是針對TestCase或者TestSuite。使用了裝飾模式來擴展的類與以上不同的是,它們功能的增強是針對任何Test實現的。如果不采用裝飾模式同樣的功能要為TestCase、TestSuite以及以后的其他Test實現分別寫出子類。因此使用裝飾模式能夠很巧妙的解決這個問題。
1.3 runner包中類設計分析
在junit.runner包。重要的是BaseTestRunner這個類,所有運行入口或者圖形界面都是集成了這個類,剩下其他的類使用反射機制來將測試類加載進來,還有讀取properties文件的操作。當然這部分也非常重要,如果想學習下反射機制的應用以及嘗試寫自己的類加載器可以閱讀這部分的源碼(關于反射技術后續會繼續分析)。
剩下的三個包這里也不作介紹,大部分的內容都是GUI的繪制(當然junit.textui包除外)。
這樣,對JUnit的整體框架有了全面的認識。總體來說各個包分工明確,設計上采用了必要的設計模式來增強了擴展性和重用性(其設計模式后續繼續分析),很值得學習和借鑒。
JUNIT源碼探秘(三):JUNIT整體執行過程分析
在閱讀Junit源碼時,需要對Junit執行測試代碼的整體過程比較了解,這樣才能夠更好的學習Junit。所以本節主要介紹下Junit的執行過程
在執行過程中使用Java Application,在執行過程中加載運行參數:
-version, 3, -port, 10115, -testLoaderClass, org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestLoader, -loaderpluginname, org.eclipse.jdt.junit.runtime, -classNames, com.wonew.junit.TestAll
當運行一個測試代碼時,先new一個TestRunner對象,同時給每一個TestRunner創建一個TestResult對象
根據代碼可以看出JUnit 的完整執行過程分為兩步:初始化加載用例集階段(getTest)、運行調度和結果捕捉階段(doRun),為了方便說嗎我們把這兩部分分解成三個階段:即初始化加載用例集階段、運行調度和結果捕捉記錄階段