注釈付きのJUnit 5条件付きテストの実行

  • link:/category/testing/ [テスト]

  • JUnit 5

1. 概要

このチュートリアルでは、https://www.baeldung.com/junit-5 [JUnit 5] *に注釈を付けて、**条件付きテストの実行を見ていきます。
これらの注釈はlink:/junit-5-extensions[JUnit Jupiter library's] _condition_パッケージからのものであり、テストを実行するまたは実行しないさまざまなタイプの条件を指定できます。

2. オペレーティングシステムの状態

場合によっては、実行しているオペレーティングシステム(OS)に応じてテストシナリオを変更する必要があります。 これらの場合、_ @ EnabledOnOs_アノテーションが役立ちます。
_ @ EnabledOnOs_の使用法は簡単です。OSタイプの値を指定するだけです。 さらに、複数のオペレーティングシステムを対象とする場合の配列引数も受け入れます。
たとえば、WindowsおよびMacOSでのみテストを実行できるようにしたいとします。
@Test
@EnabledOnOs({OS.WINDOWS, OS.MAC})
public void shouldRunBothWindowsAndMac() {
    //...
}
現在、_ @ EnabledOnOs_とは対照的に、_ @ DisabledOnOs_があります。 名前が示すように、OSタイプの引数に従ってテストを無効にします。
@Test
@DisabledOnOs(OS.LINUX)
public void shouldNotRunAtLinux() {
    //...
}

3. Javaランタイム環境の条件

また、_ @ EnableOnJre_および_ @ DisableOnJre_注釈を使用して、特定のlink:/jvm-vs-jre-vs-jdk#jre[JRE]バージョンで実行するテストをターゲットにすることもできます。 これらのアノテーションは、複数のJavaバージョンを有効または無効にする配列も受け入れます。
@Test
@EnabledOnJre({JRE.JAVA_10, JRE.JAVA_11})
public void shouldOnlyRunOnJava10And11() {
    //...
}
さらに、8、9、10、および11以外のJavaバージョンで実行されているテストを無効にする場合は、_JRE.OTHER_ _enum_プロパティを使用できます。
@Test
@DisabledOnJre(JRE.OTHER)
public void thisTestOnlyRunsWithUpToDateJREs() {
    // this test will only run on Java 8, 9, 10, and 11.
}

4. システムプロパティ条件

JVMシステムプロパティに基づいてテストを有効にする場合は、@ _ EnabledIfSystemProperty_アノテーションを使用できます。
それを使用するには、_named_および_matches_引数を提供する必要があります。 _named_引数は、正確なシステムプロパティを指定するために使用されます。 _matches_は、正規表現でプロパティ値のパターンを定義するために使用されます。
たとえば、仮想マシンのベンダー名が「Oracle」で始まる場合にのみテストを実行できるようにしたいとします。
@Test
@EnabledIfSystemProperty(named = "java.vm.vendor", matches = "Oracle.*")
public void onlyIfVendorNameStartsWithOracle() {
    //...
}
同様に、JVMシステムプロパティに基づいてテストを無効にする_ @ DisabledIfSystemProperty_があります。 この注釈を示すために、例を見てみましょう。
@Test
@DisabledIfSystemProperty(named = "file.separator", matches = "[/]")
public void disabledIfFileSeperatorIsSlash() {
    //...
}

5. 環境変数の条件

_ @ EnabledIfEnvironmentVariable_および_ @ DisabledIfEnvironmentVariable_ annotations __.__を使用して、テストの環境変数条件を指定することもできます。
また、link:#system-property-condition [system property conditions]のアノテーションと同様に、これらのアノテーションは環境変数と一致する環境変数名と正規表現を指定するための2つの引数を取ります。値:
@Test
@EnabledIfEnvironmentVariable(named = "GDMSESSION", matches = "ubuntu")
public void onlyRunOnUbuntuServer() {
    //...
}

@Test
@DisabledIfEnvironmentVariable(named = "LC_TIME", matches = ".*UTF-8.")
public void shouldNotRunWhenTimeIsNotUTF8() {
    //...
}
さらに、https://www.baeldung.com/java-system-get-property-vs-system-getenv [システムプロパティとシステム環境変数の詳細]の他のチュートリアルのいずれかを参照できます。

6. スクリプトベースの条件

さらに、JUnit 5 Jupiterでは、_ @ EnabledIf_および_ @ DisabledIf_アノテーション内にスクリプトを記述することにより、テストの実行条件を決定することができます。
これらの注釈は、3つの引数を受け入れます。
  • * value * –実行する実際のスクリプトが含まれています。

  • * engine *(オプション)-使用するスクリプトエンジンを指定します。その
    デフォルトはhttps://www.oracle.com/technetwork/articles/java/jf14-nashorn-2126515.html[Oracle Nashorn]です。

  • _ * reason * _(オプション)-ログ記録の目的で、メッセージを指定します
    テストが失敗した場合、JUnitは印刷する必要があります。

    それでは、注釈の追加引数なしで、1行のスクリプトのみを指定する簡単な例を見てみましょう。
@Test
@EnabledIf("'FR' == systemProperty.get('user.country')")
public void onlyFrenchPeopleWillRunThisMethod() {
    //...
}
また、_ @ DisabledIf_の使用法はまったく同じです。
@Test
@DisabledIf("java.lang.System.getProperty('os.name').toLowerCase().contains('mac')")
public void shouldNotRunOnMacOS() {
    //...
}
さらに、* _ value_引数を使用して複数行のスクリプトを作成できます。*
テストを実行する前に月の名前を確認する簡単な例を書いてみましょう。
サポートされているプレースホルダーを使用して、_reason_の文を定義します。
  • _ \ {annotation} _ –注釈インスタンスを表す文字列。

  • _ \ {script} _–引数内で評価されたスクリプトテキスト。

  • _ \ {result} _–の戻り値を表す文字列
    評価されたスクリプト。

    このインスタンスでは、_value_引数に複数行スクリプトがあり、_engine_および_reason_の値があります。
@Test
@EnabledIf(value = {
    "load('nashorn:mozilla_compat.js')",
    "importPackage(java.time)",
    "",
    "var thisMonth = LocalDate.now().getMonth().name()",
    "var february = Month.FEBRUARY.name()",
    "thisMonth.equals(february)"
},
    engine = "nashorn",
    reason = "On {annotation}, with script: {script}, result is: {result}")
public void onlyRunsInFebruary() {
    //...
}
*スクリプトを記述するときに、いくつかのスクリプトバインディングを使用できます。
  • systemEnvironment –システム環境変数にアクセスします。

  • systemProperty –システムプロパティ変数にアクセスします。

  • junitConfigurationParameter –構成パラメーターにアクセスします。_
    _

  • junitDisplayName –テストまたはコンテナの表示名。

  • junitTags –テストまたはコンテナのタグにアクセスします。

  • anotherUniqueId –テストまたはコンテナの一意のIDを取得します。
    _

    最後に、別の例を見て、*バインディングを使用してスクリプトを使用する方法*を見てみましょう。
@Test
@DisabledIf("systemEnvironment.get('XPC_SERVICE_NAME') != null" +
        "&& systemEnvironment.get('XPC_SERVICE_NAME').contains('intellij')")
public void notValidForIntelliJ() {
    //this method will not run on intelliJ
}
さらに、https://www.baeldung.com/spring-5-enabledIf [about__ @EnabledIf__および_ @ DisabledIf_アノテーションの詳細]の他のチュートリアルのいずれかを参照してください。

7. カスタム条件付き注釈の作成

JUnit 5に付属する非常に強力な機能は、カスタムアノテーションを作成する機能です。 *既存の条件付き注釈の組み合わせを使用して、カスタム条件付き注釈を定義できます。*
たとえば、特定のJREバージョンの特定のOSタイプに対して実行するすべてのテストを定義するとします。 このためのカスタムアノテーションを作成できます。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Test
@DisabledOnOs({OS.WINDOWS, OS.SOLARIS, OS.OTHER})
@EnabledOnJre({JRE.JAVA_9, JRE.JAVA_10, JRE.JAVA_11})
@interface ThisTestWillOnlyRunAtLinuxAndMacWithJava9Or10Or11 {
}

@ThisTestWillOnlyRunAtLinuxAndMacWithJava9Or10Or11
public void someSuperTestMethodHere() {
    // this method will run with Java9, 10, 11 and Linux or macOS.
}
さらに、*スクリプトベースの注釈を使用してカスタム注釈を作成できます*:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@DisabledIf("Math.random() >= 0.5")
@interface CoinToss {
}

@RepeatedTest(2)
@CoinToss
public void gamble() {
    // this method run run roughly 50% of the time
}

8. 結論

このチュートリアルでは、JUnit 5の注釈を使用した条件付きテストの実行について学びました。 また、それらの使用法の例をいくつか見ていきました。
次に、カスタム条件付き注釈を作成する方法を示しました。
このトピックの詳細については、https://junit.org/junit5/docs/current/user-guide/#writing-tests-conditional-execution [注釈付きの条件付きテストの実行に関するJUnit独自のドキュメント]を参照してください。
いつものように、すべてのサンプルコードはhttps://github.com/eugenp/tutorials/tree/master/testing-modules/junit-5[GitHubプロジェクト]にあります。