Junit內(nèi)部解密之: 單元測(cè)試用例運(yùn)行的全過(guò)程
我們以一個(gè)非常簡(jiǎn)單的TestCalculator類(lèi)為例,只有一個(gè)測(cè)試方法:
Public class TestCalculator extends TestCase
{
Public void testAdd()
{
Calculator calculator = new Calculator();
Double result = calculator.add(10, 50);
assertEquals(60, result);
}
}
當(dāng)我們使用Run in Junit 的時(shí)候,之前說(shuō)到過(guò)的幾個(gè)核心類(lèi)之間是怎么運(yùn)行的呢?我們先看下基本過(guò)程:
TestRunner啟動(dòng)界面框 —》創(chuàng)建一個(gè)TestSuite ––》創(chuàng)建一個(gè)TestResult—》執(zhí)行testadd方法。
由于我們的TestCalculator測(cè)試類(lèi)里面沒(méi)有顯式的suite方法,大部分情況下都是類(lèi)似,這樣的話,TestRunner創(chuàng)建了一個(gè)默認(rèn)的TestSuite對(duì)象,看下圖:
那么同時(shí)TestRunner還需要?jiǎng)?chuàng)建包含測(cè)試結(jié)果(成功,失敗或出錯(cuò))的TestResult對(duì)象,具體過(guò)程如下:
1.開(kāi)始的時(shí)候,TestRunner實(shí)例化了一個(gè)TestResult對(duì)象,在測(cè)試順序執(zhí)行的時(shí)候,這個(gè)對(duì)象將用于保存測(cè)試結(jié)果。
2.TestRunner向TestResult注冊(cè),是add一個(gè)監(jiān)聽(tīng)器,這樣的話在執(zhí)行測(cè)試過(guò)程中,TestRunner可以收到各種事件,TestResult會(huì)廣播如下方法:測(cè)試開(kāi)始(startTest); 測(cè)試失敗(addFailure); 遇到測(cè)試錯(cuò)誤(addError); 測(cè)試結(jié)束(endTest)
3.知道了這些事件后,TestRunner可以隨著測(cè)試的進(jìn)行而顯示進(jìn)度條了,并且在失敗或錯(cuò)誤的時(shí)候顯示出來(lái)。
4.TestRunner通過(guò)調(diào)用TestSuite的run(TestResult)方法來(lái)開(kāi)始測(cè)試
5.TestSuite為它所擁有的每個(gè)Test Case實(shí)例調(diào)用run(TestResult)方法。
6.Test Case使用傳遞給它的TestResult實(shí)例來(lái)調(diào)用其run(Test)方法,并把自身作為參數(shù)傳遞給run方法,這樣TestResult 立馬可以用runBare()來(lái)回調(diào)它。
接著是執(zhí)行測(cè)試方法了:
這里需要說(shuō)明的是對(duì)于每個(gè)TestCase都會(huì)調(diào)用runBare()方法,這里只有一個(gè)testAdd方法,所以只調(diào)用一次,請(qǐng)看下圖:
1.runBare()方法將調(diào)用setUp, testAdd, teardown 方法,順序執(zhí)行。
2.如果調(diào)用3個(gè)方法的過(guò)程出現(xiàn)任何失敗或錯(cuò)誤,那么TestResult會(huì)分別調(diào)用addFailure 和addError來(lái)通知它的所有Listener。
3.這樣TestRunner會(huì)收到這些錯(cuò)誤或失敗,也會(huì)羅列出這些錯(cuò)誤,否則進(jìn)度條是綠色的,讓你知道測(cè)試方法沒(méi)有問(wèn)題。
4.當(dāng)tearDown方法執(zhí)行完后,測(cè)試也完成了,TestResult 會(huì)通過(guò)調(diào)用endTest把這個(gè)結(jié)果通告給所有的Listener。