1. 概要

このチュートリアルでは、 JUnit5のアノテーションを使用した条件付きテストの実行を見ていきます。

これらのアノテーションは、JUnitJupiterライブラリの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アノテーションを使用して、特定のJREバージョンで実行するようにテストをターゲットにすることもできます。 これらのアノテーションは、複数のJavaバージョンを有効または無効にする配列も受け入れます。

@Test
@EnabledOnJre({JRE.JAVA_10, JRE.JAVA_11})
public void shouldOnlyRunOnJava10And11() {
    //...
}

JUnit 5.6以降、 @EnabledForJreRange を使用して、特定の範囲のJavaバージョンのテストを有効にすることができます。

@Test
@EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_13)
public void shouldOnlyRunOnJava8UntilJava13() {
    // this test will only run on Java 8, 9, 10, 11, 12, and 13.
}

デフォルトでは、最小値は JAVA_8 であり、最大値は可能な最大のJREバージョンです。 @DisabledForJreRange もあり、特定の範囲のJavaバージョンのテストを無効にします。

@Test
@DisabledForJreRange(min = JRE.JAVA_14, max = JRE.JAVA_15)
public void shouldNotBeRunOnJava14AndJava15() {
    // this won't run on Java 14 and 15.
}

さらに、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 は、正規表現を使用してプロパティ値のパターンを定義するために使用されます。

たとえば、仮想マシンのベンダー名が「Oracle」で始まる場合にのみテストを実行できるようにするとします。

@Test
@EnabledIfSystemProperty(named = "java.vm.vendor", matches = "Oracle.*")
public void onlyIfVendorNameStartsWithOracle() {
    //...
}

同様に、 @DisabledIfSystemProperty を使用して、JVMシステムプロパティに基づくテストを無効にします。 この注釈を示すために、例を見てみましょう。

@Test
@DisabledIfSystemProperty(named = "file.separator", matches = "[/]")
public void disabledIfFileSeperatorIsSlash() {
    //...
}

5. 環境変数条件

@EnabledIfEnvironmentVariableおよび@DisabledIfEnvironmentVariable注釈を使用してテストの環境変数条件を指定することもできます。

また、システムプロパティ条件のアノテーションと同様に、これらのアノテーションは、名前付き一致-の2つの引数を取り、環境変数名と一致する正規表現を指定します。環境変数値に対して:

@Test
@EnabledIfEnvironmentVariable(named = "GDMSESSION", matches = "ubuntu")
public void onlyRunOnUbuntuServer() {
    //...
}

@Test
@DisabledIfEnvironmentVariable(named = "LC_TIME", matches = ".*UTF-8.")
public void shouldNotRunWhenTimeIsNotUTF8() {
    //...
}

さらに、他のチュートリアルの1つを参照して、システムプロパティとシステム環境変数の詳細を学ぶことができます。

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

6.1. 非推奨の通知

スクリプトベースの条件APIとその実装は、JUnit 5.5で非推奨になり、JUnit5.6から削除されました。 同じ結果を得るには、組み込みの条件を組み合わせて使用するか、ExecutionCondition。のカスタム実装を作成することを強くお勧めします。

6.2. 条件

JUnit 5.6より前では、@EnabledIfおよび@DisabledIfアノテーション内にスクリプトを記述することで、テストの実行条件を指定できました。

これらの注釈は、次の3つの引数を受け入れます。

  • value –実行する実際のスクリプトが含まれています。
  • engine (オプション)–使用するスクリプトエンジンを指定します。 デフォルトはOracleNashornです。
  • 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 引数に複数行のスクリプトがあり、enginereasonの値は次のとおりです。

@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
}

さらに、他のチュートリアルの1つを参照して、@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. 結論

この記事では、JUnit5でのアノテーションを使用した条件付きテストの実行について学習しました。 また、それらの使用例をいくつか紹介しました。

次に、カスタム条件付きアノテーションを作成する方法を確認しました。

このトピックの詳細については、アノテーション付きの条件付きテストの実行に関するJUnitのドキュメントを参照してください。

いつものように、この記事のすべてのサンプルコードは、GitHubにあります。