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

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

1. 概要

この簡単な記事では、カスタムテストランナーを使用してJUnitテストを実行する方法に焦点を当てます。

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

2. 準備

標準のJUnit依存関係をpom.xmlに追加することから始めましょう。


  junit
  junit
  4.12

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

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

A JUnit Runner is a class that extends JUnit’s abstract Runner class and it is responsible for running JUnit tests、通常は反射を使用します。

ここでは、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);
        }
    }
}

getDescription メソッドは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.example.junit.CalculatorTest
running the tests from MyRunner: class com.example.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クラスを拡張する代わりに、we can extend one of the specialized subclasses of Runner: ParentRunner or 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では常にデフォルトのJUnit4ランナーが呼び出されます。このクラスは、現在のデフォルトのJUnit4クラスランナーのエイリアスです。

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

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

5. 結論

JUnit Runnerは非常に適応性が高く、開発者はテスト実行手順とテストプロセス全体を変更できます。

小さな変更のみを行う場合は、BlockJUnit4Classランナーの保護されたメソッドを確認することをお勧めします。

使用するランナーの一般的なサードパーティ実装には、SpringJUnit4ClassRunner, MockitoJUnitRunner, HierarchicalContextRunner,Cucumber Runnerなどがあります。

これらすべての例とコードスニペットの実装は、GitHub projectにあります。これはMavenプロジェクトであるため、そのままインポートして実行するのは簡単です。