JunitのテストケースはJunitCore.run(クラスクラス)を開始するには、次の分析は、Junitはどのようにケースの使用の実行をトリガすることです。
ランナーの取得
public Result run(Class<?>... classes) {
return run(defaultComputer(), classes);
}
入力パラメータは Class オブジェクトで、テストケースをホストするテストクラスを表します。 run(defaultComputer(), classes) の分析を続け、Computer.class に注目します。
public class Computer {
15 /**
16 * Returns a new default computer, which runs tests in serial order
17 */
18 public static Computer serial() {
19 return new Computer();
20 }
21
22 /**
23 * Create a suite for {@code classes}, building Runners with {@code builder}.
24 * Throws an InitializationError if Runner construction fails
25 */
26 public Runner getSuite(final RunnerBuilder builder,
27 Class<?>[] classes) throws InitializationError {
28 return new Suite(new RunnerBuilder() {
29 @Override
30 public Runner runnerForClass(Class<?> testClass) throws Throwable {
31 return getRunner(builder, testClass);
32 }
33 }, classes);
34 }
35
36 /**
37 * Create a single-class runner for {@code testClass}, using {@code builder}
38 */
39 protected Runner getRunner(RunnerBuilder builder, Class<?> testClass) throws Throwable {
40 return builder.runnerForClass(testClass);
41 }
42}
このクラスは比較的シンプルで、次の3つの関数から構成されています。
- serial(): 静的インターフェイス、フィードバック Computer オブジェクト、コンストラクタに似た関数
- getSuite(): 指定したテストクラスコレクション、スイートコードのテストクラスコレクションのランナー情報を取得します。
- 指定したテストクラスのランナーを取得します。
このタイプの主な機能は、テストケースのランナーを取得することであることがわかります。
public Result run(Computer computer, Class<?>... classes) {
return run(Request.classes(computer, classes));
}
次に run(Request request) をネストして、Request クラスの分析を続けます。
junit/src/main/java/org/junit/runner/Request.java
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");
}
}
Requestオブジェクトは静的メソッドクラスを通して構築されます。
AllDefaultPossibilitiesBuilder
RunnerBuilderのサブクラスで、Runnerをパースするための基本的なルールを指定する抽象クラスです。
runnerForClassメソッドで分析し、次にAllDefaultPossibilitiesBuilderが何をしたかを具体的に見る
public class AllDefaultPossibilitiesBuilder extends RunnerBuilder {
10 private final boolean canUseSuiteMethod;
11
12 public AllDefaultPossibilitiesBuilder(boolean canUseSuiteMethod) {
13 this.canUseSuiteMethod = canUseSuiteMethod;
14 }
15
16 @Override
17 public Runner runnerForClass(Class<?> testClass) throws Throwable {
18 List<RunnerBuilder> builders = Arrays.asList(
19 ignoredBuilder(),
20 annotatedBuilder(),
21 suiteMethodBuilder(),
22 junit3Builder(),
23 junit4Builder());
24
25 for (RunnerBuilder each : builders) {
26 Runner runner = each.safeRunnerForClass(testClass);
27 if (runner != null) {
28 return runner;
29 }
30 }
31 return null;
32 }
33
34 protected JUnit4Builder junit4Builder() {
35 return new JUnit4Builder();
36 }
37
38 protected JUnit3Builder junit3Builder() {
39 return new JUnit3Builder();
40 }
41
42 protected AnnotatedBuilder annotatedBuilder() {
43 return new AnnotatedBuilder(this);
44 }
45
46 protected IgnoredBuilder ignoredBuilder() {
47 return new IgnoredBuilder();
48 }
49
50 protected RunnerBuilder suiteMethodBuilder() {
51 if (canUseSuiteMethod) {
52 return new SuiteMethodBuilder();
53 }
54 return new NullBuilder();
55 }
56}
public Runner getSuite(final RunnerBuilder builder,
27 Class<?>[] classes) throws InitializationError {
28 return new Suite(new RunnerBuilder() {
29 @Override
30 public Runner runnerForClass(Class<?> testClass) throws Throwable {
31 return getRunner(builder, testClass);
32 }
33 }, classes);
34 }
SuiteのコンストラクタにはRunnerBuilderとClassの2つの入力があり、Classはこれ以上説明する必要はありません。
この時点で、ユースケースを実行するRunnerが取得され、次のステップはユースケースを実行することです。
テストケースの実行
public Result run(Runner runner) {
132 Result result = new Result();//ユースケースの実行結果を格納する Result クラスをインスタンス化する。
133 RunListener listener = result.createListener();//新しい実行リスナーを作成し、ユースケースの実行状況(pass、fail、ignore など)を聞く。
134 notifier.addFirstListener(listener);//リスナーを設定する
135 try {
136 notifier.fireTestRunStarted(runner.getDescription());//ユースケースの実行を開始する
137 runner.run(notifier);//ユースケースを実行する
138 notifier.fireTestRunFinished(result);//結果を保存する
139 } finally {
140 removeListener(listener);
141 }
142 return result;
143 }
ランの流れは、この後のカスタムランナーの紹介で再度分析します。