JUnit 4からJUnit 5への移行

JUnit 4からJUnit 5への移行

1. 概要

この記事では、JUnit4から最新のJUnit5リリースに移行する方法と、2つのバージョンのライブラリの違いの概要を説明します。

JUnit 5の使用に関する一般的なガイドラインについては、記事hereを参照してください。

2. JUnit 5の利点

以前のバージョンから始めましょう– JUnit4にはいくつかの明確な制限があります。

  • フレームワーク全体が単一のjarライブラリに含まれていました。 特定の機能のみが必要な場合でも、ライブラリ全体をインポートする必要があります。 In JUnit 5, we get more granularity and can import only what is necessary

  • 1人のテストランナーが一度に実行できるテストは、JUnit 4のみです(例: SpringJUnit4ClassRunnerまたはParameterized)。 JUnit 5 allows multiple runners to work simultaneously

  • JUnit 4はJava 7を超えて進化することはありませんでした。Java8の多くの機能を利用できませんでした。 JUnit 5 makes good use of Java 8 features

JUnit 5の背後にあるアイデアは、JUnit 4を完全に書き直してこれらの欠点のほとんどを解決することでした。

3. 違い

JUnit 4は、JUnit 5を構成するモジュールに分割されました。

  • JUnit Platform –このモジュールは、テストの実行、検出、およびレポートに関心がある可能性のあるすべての拡張フレームワークを対象としています

  • JUnit Vintage –このモジュールは、JUnit4またはJUnit3との下位互換性を可能にします

3.1. アノテーション

JUnit 5のアノテーションには重要な変更が加えられています。 The most important one is that we can no longer use @Test annotation for specifying expectations.

JUnit 4のexpectedパラメータ:

@Test(expected = Exception.class)
public void shouldRaiseAnException() throws Exception {
    // ...
}

これで、メソッドassertThrowsを使用できます。

public void shouldRaiseAnException() throws Exception {
    Assertions.assertThrows(Exception.class, () -> {
        //...
    });
}

JUnit 4のtimeout属性:

@Test(timeout = 1)
public void shouldFailBecauseTimeout() throws InterruptedException {
    Thread.sleep(10);
}

ここで、JUnit 5のassertTimeoutメソッドは次のとおりです。

@Test
public void shouldFailBecauseTimeout() throws InterruptedException {
    Assertions.assertTimeout(Duration.ofMillis(1), () -> Thread.sleep(10));
}

JUnit 5内で変更されたその他の注釈:

  • @Beforeアノテーションは@BeforeEachに名前が変更されました

  • @Afterアノテーションは@AfterEachに名前が変更されました

  • @BeforeClassアノテーションは@BeforeAllに名前が変更されました

  • @AfterClassアノテーションは@AfterAllに名前が変更されました

  • @Ignoreアノテーションは@Disabledに名前が変更されました

3.2. アサーション

JUnit 5のラムダにアサーションメッセージを書き込むことができるようになりました。遅延評価では、必要になるまで複雑なメッセージの構築をスキップできます。

@Test
public void shouldFailBecauseTheNumbersAreNotEqual_lazyEvaluation() {
    Assertions.assertTrue(
      2 == 3,
      () -> "Numbers " + 2 + " and " + 3 + " are not equal!");
}

JUnit 5でアサーションをグループ化することもできます。

@Test
public void shouldAssertAllTheGroup() {
    List list = Arrays.asList(1, 2, 4);
    Assertions.assertAll("List is not incremental",
        () -> Assertions.assertEquals(list.get(0).intValue(), 1),
        () -> Assertions.assertEquals(list.get(1).intValue(), 2),
        () -> Assertions.assertEquals(list.get(2).intValue(), 3));
}

3.3. 仮定

新しいAssumptionsクラスがorg.junit.jupiter.api.Assumptionsになりました。 JUnit 5は、JUnit 4の既存の仮定メソッドを完全にサポートし、特定のシナリオでのみ一部のアサーションを実行できるようにする一連の新しいメソッドを追加します。

@Test
public void whenEnvironmentIsWeb_thenUrlsShouldStartWithHttp() {
    assumingThat("WEB".equals(System.getenv("ENV")),
      () -> {
          assertTrue("http".startsWith(address));
      });
}

3.4. タグ付けとフィルタリング

JUnit 4では、@Categoryアノテーションを使用してテストをグループ化できました。 JUnit 5では、@Categoryアノテーションが@Tagアノテーションに置き換えられます。

@Tag("annotations")
@Tag("junit5")
@RunWith(JUnitPlatform.class)
public class AnnotationTestExampleTest {
    /*...*/
}

maven-surefire-pluginを使用して、特定のタグを含めたり除外したりできます。


    
        
            maven-surefire-plugin
            
                
                    junit5
                
            
        
    

3.5. テストを実行するための新しい注釈

@RunWithは、テストコンテキストを他のフレームワークと統合するため、またはJUnit4のテストケースの全体的な実行フローを変更するために使用されました。

JUnit 5では、@ExtendWithアノテーションを使用して同様の機能を提供できるようになりました。

例として、JUnit 4でSpring機能を使用するには:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(
  {"/app-config.xml", "/test-data-access-config.xml"})
public class SpringExtensionTest {
    /*...*/
}

JUnit 5では、これは単純な拡張機能です。

@ExtendWith(SpringExtension.class)
@ContextConfiguration(
  { "/app-config.xml", "/test-data-access-config.xml" })
public class SpringExtensionTest {
    /*...*/
}

3.6. 新しいテストルールの注釈

JUnit 4では、@Ruleおよび@ClassRuleアノテーションを使用して、テストに特別な機能を追加しました。

JUnit 5で。 @ExtendWithアノテーションを使用して同じロジックを再現できます。

たとえば、テストの前後にログトレースを書き込むためのJUnit 4のカスタムルールがあるとします。

public class TraceUnitTestRule implements TestRule {

    @Override
    public Statement apply(Statement base, Description description) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                // Before and after an evaluation tracing here
                ...
            }
        };
    }
}

そして、テストスイートに実装します。

@Rule
public TraceUnitTestRule traceRuleTests = new TraceUnitTestRule();

JUnit 5では、はるかに直感的な方法で同じことを記述できます。

public class TraceUnitExtension implements AfterEachCallback, BeforeEachCallback {

    @Override
    public void beforeEach(TestExtensionContext context) throws Exception {
        // ...
    }

    @Override
    public void afterEach(TestExtensionContext context) throws Exception {
        // ...
    }
}

パッケージorg.junit.jupiter.api.extension,で利用可能なJUnit 5のAfterEachCallbackおよびBeforeEachCallbackインターフェースを使用して、このルールをテストスイートに簡単に実装します。

@RunWith(JUnitPlatform.class)
@ExtendWith(TraceUnitExtension.class)
public class RuleExampleTest {

    @Test
    public void whenTracingTests() {
        /*...*/
    }
}

3.7. JUnit 5ヴィンテージ

JUnit Vintageは、JUnit 5コンテキスト内でJUnit 3またはJUnit 4テストを実行することにより、JUnitテストの移行を支援します。

JUnit Vintage Engineをインポートすることで使用できます。


    org.junit.vintage
    junit-vintage-engine
    ${junit5.vintage.version}
    test

4. 結論

この記事で見てきたように、JUnit 5は、JUnit4フレームワークをモジュール化した最新の方法です。 これら2つのバージョンの主な違いを紹介し、あるバージョンから別のバージョンに移行する方法を示しました。

このチュートリアルの完全な実装は、over on GitHubにあります。