カスタムJUnit4テストランナー
1. 概要
このクイック記事では、カスタムテストランナーを使用してJUnitテストを実行する方法に焦点を当てます。
簡単に言うと、カスタムランナーを指定するには、@RunWithアノテーションを使用する必要があります。
2. 準備
標準の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);
}
}
}
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.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では常にデフォルトの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ランナーは適応性が高く、開発者がテスト実行手順とテストプロセス全体を変更できるようにします。
小さな変更のみを行う場合は、BlockJUnit4Classランナーの保護されたメソッドを確認することをお勧めします。
使用するランナーの一般的なサードパーティ実装には、 SpringJUnit4ClassRunner、MockitoJUnitRunner、HierarchicalContextRunner、 CucumberRunnerなどがあります。
これらすべての例とコードスニペットの実装は、 GitHubプロジェクトにあります。これはMavenプロジェクトであるため、そのままインポートして実行するのは簡単です。