標籤:des style blog color io os ar strong for
第一次寫原始碼分析,介紹運行流程和其中重要的類和介面!
JUnitCore
JUnitCore採用門面模式,可以啟動junit4,junit3測試,也可以測試指定class。JUnitCore聲明RunNotifier類,該類採用觀察者模式實現事件管理。RunListener為測試事件基類,有測試開始結束失敗等事件,如果想自訂事件可以繼承該類。預設增加了兩個RunListener,一個是TextListener,另一個是Result類函數createListener構造的Listener用於記錄開始結束時間、執行總數、失敗總數等。可看到run方法調用前觸發了fireTestRunStarted,執行後觸發了fireTestRunFinished。關鍵代碼(截取)
private final RunNotifier notifier = new RunNotifier(); Result runMain(JUnitSystem system, String... args) { RunListener listener = new TextListener(system); addListener(listener); return run(jUnitCommandLineParseResult.createRequest(defaultComputer())); } public Result run(Request request) { return run(request.getRunner()); } public Result run(Runner runner) { Result result = new Result(); RunListener listener = result.createListener(); notifier.addFirstListener(listener); try { notifier.fireTestRunStarted(runner.getDescription()); runner.run(notifier); notifier.fireTestRunFinished(result); } finally { removeListener(listener); } return result; }
Request
對class和test的封裝,可以是一個class下所有test、所有class下所有test、還可以結合filter。classes方法擷取suite,suite裡包含各個類的runner。關鍵代碼(截取)
public static Request classes(Computer computer, Class<?>... classes) { try { AllDefaultPossibilitiesBuilder builder = new AllDefaultPossibilitiesBuilder(true); Runner suite = computer.getSuite(builder, classes); return runner(suite); } catch (InitializationError e) { throw new RuntimeException( "Bug in saff‘s brain: Suite constructor, called as above, should always complete"); } }
RunnerBuilder
建立runner採用builder模式,對於每一個class產生一個runner。
private List<Runner> runners(Class<?>[] children) { ArrayList<Runner> runners = new ArrayList<Runner>(); for (Class<?> each : children) { Runner childRunner = safeRunnerForClass(each); if (childRunner != null) { runners.add(childRunner); } } return runners; }
AllDefaultPossibilitiesBuilder
選擇具體builder,預設為junit4Builder,如果class有@Ignore標註則為IgnoredBuilder,如果class有@RunWith標註則為IgnoredBuilder,如果測試方法有suite則為SuiteMethodBuilder,如果class繼承於junit.framework.TestCase則為JUnit38ClassRunner,否則預設時用JUnit4Builder返回BlockJUnit4ClassRunner
public Runner runnerForClass(Class<?> testClass) throws Throwable { List<RunnerBuilder> builders = Arrays.asList( ignoredBuilder(), annotatedBuilder(), suiteMethodBuilder(), junit3Builder(), junit4Builder()); for (RunnerBuilder each : builders) { Runner runner = each.safeRunnerForClass(testClass); if (runner != null) { return runner; } } return null; }
junit4.12源碼分析-啟動到選擇runner