blog

Junitのテストケースは、次のように実行する。

コンストラクタは非常にシンプルで、コードを通過させるだけです。...

Nov 13, 2020 · 4 min. read
シェア

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つの関数から構成されています。

  1. serial(): 静的インターフェイス、フィードバック Computer オブジェクト、コンストラクタに似た関数
  2. getSuite(): 指定したテストクラスコレクション、スイートコードのテストクラスコレクションのランナー情報を取得します。
  3. 指定したテストクラスのランナーを取得します。

このタイプの主な機能は、テストケースのランナーを取得することであることがわかります。

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 }

ランの流れは、この後のカスタムランナーの紹介で再度分析します。

Read next

Mysql - データベースの基本

データベースのデータを整理するためにリレーショナルモデルを使用することを指し、リレーショナルモデルは2次元テーブルモデルを指し、リレーショナルデータベースは2次元テーブルとデータ組織の構成間のリンクで構成されています。 保守が容易: リッチインテグリティは、データの冗長性やデータの不整合が発生する確率を大幅に低減します。 カラムが不可分である原子性が重視されます。例えば、テーブル...

Nov 12, 2020 · 6 min read