カスタムJUnit 4テストランナー

1概要

このクイック記事では、カスタムテストランナーを使ってJUnitテストを実行する方法に焦点を当てます。

簡単に言うと、カスタムランナーを指定するには、 @ RunWith アノテーションを使用する必要があります。

2準備

まず標準のhttps://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22junit%22[ JUnit ]依存関係を pom.xml に追加します。

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.12</version>
</dependency>

3カスタムランナーの実装

次の例では、独自のカスタム Runner を作成し、@ RunWith を使用して実行する方法を示します。

  • JUnit RunnerはJUnitの抽象 Runner クラスを拡張するクラスであり、通常はリフレクションを使用してJUnitテスト** を実行します。

ここでは、 Runner クラスの抽象メソッドを実装しています。

public class TestRunner extends Runner {

    private Class testClass;
    public TestRunner(Class testClass) {
        super();
        this.testClass = testClass;
    }

    @Override
    public Description getDescription() {
        return Description
          .createTestDescription(testClass, "My runner description");
    }

    @Override
    public void run(RunNotifier notifier) {
        System.out.println("running the tests from MyRunner: " + testClass);
        try {
            Object testObject = testClass.newInstance();
            for (Method method : testClass.getMethods()) {
                if (method.isAnnotationPresent(Test.class)) {
                    notifier.fireTestStarted(Description
                      .createTestDescription(testClass, method.getName()));
                    method.invoke(testObject);
                    notifier.fireTestFinished(Description
                      .createTestDescription(testClass, method.getName()));
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

このメソッドは Describable から継承され、後でエクスポートされる情報を含む Description を返します。これはさまざまなツールで使用できます。

run 実装では、リフレクションを使用してターゲットのテストメソッドを呼び出しています。

Class 引数を取るコンストラクタを定義しました。これはJUnitの要件です。実行時に、JUnitはターゲットのテストクラスをこのコンストラクタに渡します。

RunNotifier は、テストの進行状況に関する情報を持つイベントを発生させるために使用されます。

テストクラスでランナーを使用しましょう。

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
}

@RunWith(TestRunner.class)
public class CalculatorTest {
    Calculator calculator = new Calculator();

    @Test
    public void testAddition() {
        Syste.out.println("in testAddition");
        assertEquals("addition", 8, calculator.add(5, 3));
    }
}

結果は次のとおりです。

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.baeldung.junit.CalculatorTest
running the tests from MyRunner: class com.baeldung.junit.CalculatorTest
in testAddition
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.002 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

4専門ランナー

最後の例で行ったように、低レベルの Runner クラスを拡張する代わりに、** Runner の特殊なサブクラスの1つを拡張できます。

ParentRunner または BlockJUnit4Runner 。**

抽象 ParentRunner クラスは階層的にテストを実行します。

BlockJUnit4Runner は具象クラスです。特定のメソッドをカスタマイズしたい場合は、おそらくこのクラスを拡張することになります。

例を見てみましょう。

public class BlockingTestRunner extends BlockJUnit4ClassRunner {
    public BlockingTestRunner(Class<?> klass) throws InitializationError {
        super(klass);
    }

    @Override
    protected Statement methodInvoker(FrameworkMethod method, Object test) {
        System.out.println("invoking: " + method.getName());
        return super.methodInvoker(method, test);
    }
}

@ RunWith(JUnit4.class) を使用してクラスに注釈を付けると、常に現在のバージョンのJUnitのデフォルトのJUnit 4ランナーが呼び出されます。このクラスは現在のデフォルトのJUnit 4クラスランナーをエイリアスします。

@RunWith(JUnit4.class)
public class CalculatorTest {
    Calculator calculator = new Calculator();

    @Test
    public void testAddition() {
        assertEquals("addition", 8, calculator.add(5, 3));
    }
}

5結論

JUnitランナーは非常に適応性があり、開発者にテスト実行手順とテストプロセス全体を変更させます。

ちょっとした変更を加えたいだけであれば、 BlockJUnit4Class ランナーのprotectedメソッドを見てみるのはいい考えです。

使用するためのランナーのいくつかの人気のあるサードパーティの実装は SpringJUnit4ClassRunner、MockitoJUnitRunner、HierarchicalContextRunner、 Cucumber Runner などを含みます。

これらすべての例とコードスニペットの実装はhttps://github.com/eugenp/tutorials/tree/master/testing-modules/testing[GitHubプロジェクト]にあります - これはMavenプロジェクトです。そのままインポートして実行するのは簡単です。