從上圖可以看出,我們的并行測(cè)試用例通過(guò)了測(cè)試,并且它們?cè)谑褂貌煌程運(yùn)行時(shí)都能正常的工作。而串行的測(cè)試方法 (doNothing) 的執(zhí)行結(jié)果則完全和之前一樣工作正常。也是說(shuō),串行和并行測(cè)試可以在一個(gè)測(cè)試類中同時(shí)出現(xiàn)。
Annotation 詳細(xì)說(shuō)明
表 1. 擴(kuò)展的 annotation 說(shuō)明
擴(kuò)展 JUnit 的過(guò)程說(shuō)明
歸功于 JUnit 的靈活的內(nèi)部架構(gòu),只要遵循 JUnit 的標(biāo)準(zhǔn),我們能夠輕松的擴(kuò)展 JUnit 的功能。而且遵循標(biāo)準(zhǔn)還意味著我們的擴(kuò)展能無(wú)縫的利用社區(qū)對(duì) JUnit 的廣泛支持。例如,我們沒(méi)有編寫任何 Eclipse 插件,但是我們的測(cè)試結(jié)果能自然的在 Eclipse 中通過(guò)精心設(shè)計(jì)的 GUI 進(jìn)行展現(xiàn)。
言歸正傳,我們擴(kuò)展 JUnit 的過(guò)程主要由以下過(guò)程組成:
生成 Annotation 的定義,包括:@Threaded, @InitFor, @Check, @ParallelSetting
生成 TestClassRunner 的子類 Parallelized 并在其中實(shí)現(xiàn)運(yùn)行自定義測(cè)試的邏輯
生成 TestMethodRunner 的子類供 Parallelized 類使用
在實(shí)現(xiàn) ThreadedMethodRunner 時(shí),我們開始在類 ThreadedMethodRunner 使用了 Thread 類的 setDefaultUncaughtExceptionHandler 來(lái)捕獲異常。然后將異常封裝到主線程。而目前的版本則利用了 Executor 來(lái)運(yùn)行多線程測(cè)試。由于 JDK 中的 Future 已經(jīng)提供了類似的能力,所以我們不需要再關(guān)心異常的正確傳遞問(wèn)題了。 JUnit 能準(zhǔn)確的打印出并行測(cè)試中產(chǎn)生的異常信息,這也意味著我們可以使用 JUnit 提供的 Assert 功能了。
結(jié)論
隨著多核平臺(tái)逐漸成為主流,開發(fā)人員不可避免地需要開發(fā)和測(cè)試并行應(yīng)用。本文通過(guò)使用 Annotation 擴(kuò)展 JUnit,使其可以更方便地支持“準(zhǔn)備數(shù)據(jù)——多線程運(yùn)行——檢查結(jié)果”三階段的并行測(cè)試模式,減少開發(fā)人員手工創(chuàng)建線程和同步的繁瑣工作。并且可以使 JUnit 支持從子線程中捕獲測(cè)試錯(cuò)誤,正確地在 Eclipse 等 IDE 中顯示測(cè)試結(jié)果。