1. 概要

典型的なテスト駆動開発では、実行とセットアップが高速な低レベルの単体テストを多数作成することを目指しています。 さらに、サーバーやデータベースのセットアップなど、外部システムに依存する高レベルの統合テストもほとんどありません。 当然のことながら、これらは通常、リソースと時間の両方を伴います。

したがって、これらのテストでは、ほとんどの場合、正常な終了のために統合前のセットアップと統合後のクリーンアップが必要です。 したがって、2つのタイプのテストを区別し、ビルドプロセス。

このチュートリアルでは、一般的な ApacheMavenビルドでさまざまなタイプのテストを実行するために最も一般的に使用されるSurefireプラグインとFailsafeプラグインを比較します。

2. Surefireプラグイン

Surefireプラグインは、Maven core プラグインのセットに属し、アプリケーションの単体テストを実行します。

プロジェクトPOMにはデフォルトでこのプラグインが含まれていますが、明示的に構成することもできます。

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M5</version>
                ....
            </plugin>
         </plugins>
    </pluginManagement>
</build>

プラグインは、デフォルトのライフサイクルテストフェーズにバインドします。 したがって、次のコマンドで実行してみましょう。

mvn clean test

これにより、プロジェクトのすべての単体テストが実行されます。 Surefireプラグインはテストフェーズにバインドされるため、テストが失敗した場合、ビルドは失敗し、ビルドプロセス中にそれ以上のフェーズは実行されません

または、プラグイン構成を変更して、統合テストと単体テストを実行することもできます。 ただし、これは、統合テストでは望ましくない動作である可能性があります。統合テストでは、テスト実行前の環境設定と、テスト実行後のクリーンアップが必要になる場合があります。

Mavenは、まさにこの目的のために別のプラグインを提供します。

3. フェイルセーフプラグイン

Failsafeプラグインは、プロジェクトで統合テストを実行するように設計されています。

3.1. 構成

まず、プロジェクトPOMでこれを構成しましょう。

<plugin>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>3.0.0-M5</version>
    <executions>
        <execution>
            <goals>
                <goal>integration-test</goal>
                <goal>verify</goal>
            </goals>
            ....
        </execution>
    </executions>
</plugin>

ここで、プラグインの目標は、統合テストを実行するために、ビルドサイクルの統合テストおよび検証フェーズにバインドされます。

それでは、コマンドラインからverifyフェーズを実行してみましょう。

mvn clean verify

これはすべての統合テストを実行しますが、統合テストフェーズ中にテストが失敗した場合、プラグインはすぐにビルドに失敗しません

代わりに、Mavenは統合後テストフェーズを実行します。 したがって、統合後テストフェーズの一部として、クリーンアップと環境の分解を実行できます。 ビルドプロセスの後続のverifyフェーズでは、テストの失敗が報告されます。

3.2. 例

この例では、統合テストを実行する前に開始し、テストの実行後に停止するようにJettyサーバーを構成します。

まず、JettyプラグインをPOMに追加しましょう。

<plugin>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <version>9.4.11.v20180605</version>
    ....
    <executions>
        <execution>
            <id>start-jetty</id>
            <phase>pre-integration-test</phase>
            <goals>
                <goal>start</goal>
            </goals>
        </execution>
        <execution>
            <id>stop-jetty</id>
            <phase>post-integration-test</phase>
            <goals>
                <goal>stop</goal>
            </goals>
        </execution>
    </executions>
</plugin>

ここでは、pre-integration-testフェーズとpost-integration-testフェーズでそれぞれJettyサーバーを起動および停止するための構成を追加しました。

それでは、統合テストをもう一度実行して、コンソールの出力を見てみましょう。

....
[INFO] <<< jetty-maven-plugin:9.4.11.v20180605:start (start-jetty) 
  < validate @ maven-integration-test <<<
[INFO] --- jetty-maven-plugin:9.4.11.v20180605:start (start-jetty)
  @ maven-integration-test ---
[INFO] Started ServerConnector@4b9dc62f{HTTP/1.1,[http/1.1]}{0.0.0.0:8999}
[INFO] Started @6794ms
[INFO] Started Jetty Server
[INFO]
[INFO] --- maven-failsafe-plugin:3.0.0-M5:integration-test (default)
  @ maven-integration-test ---
[INFO]
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.baeldung.maven.it.FailsafeBuildPhaseIntegrationTest
[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.024 s
  <<< FAILURE! - in com.baeldung.maven.it.FailsafeBuildPhaseIntegrationTest
[ERROR] com.baeldung.maven.it.FailsafeBuildPhaseIntegrationTest.whenTestExecutes_thenPreAndPostIntegrationBuildPhasesAreExecuted
  Time elapsed: 0.012 s  <<< FAILURE!
org.opentest4j.AssertionFailedError: expected: <true> but was: <false>
	at com.baeldung.maven.it.FailsafeBuildPhaseIntegrationTest
          .whenTestExecutes_thenPreAndPostIntegrationBuildPhasesAreExecuted(FailsafeBuildPhaseIntegrationTest.java:11)
[INFO]
[INFO] Results:
[INFO]
[ERROR] Failures:
[ERROR]   FailsafeBuildPhaseIntegrationTest.whenTestExecutes_thenPreAndPostIntegrationBuildPhasesAreExecuted:11
  expected: <true> but was: <false>
[INFO]
[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
[INFO]
[INFO] --- jetty-maven-plugin:9.4.11.v20180605:stop (stop-jetty)
  @ maven-integration-test ---
[INFO]
[INFO] --- maven-failsafe-plugin:3.0.0-M5:verify (default)
  @ maven-integration-test ---
[INFO] Stopped ServerConnector@4b9dc62f{HTTP/1.1,[http/1.1]}{0.0.0.0:8999}
[INFO] node0 Stopped scavenging
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
....

ここでは、構成に従って、統合テストの実行前にJettyサーバーが起動します。 デモンストレーションでは、統合テストが失敗しますが、ビルドがすぐに失敗するわけではありません。 post-integration-test フェーズはテスト実行後に実行され、サーバーはビルドが失敗する前に停止します。

対照的に、Surefireプラグインを使用してこれらの統合テストを実行すると、必要なクリーンアップを実行せずに、ビルドは統合テストフェーズで停止します

さまざまなタイプのテストにさまざまなプラグインを使用することの追加の利点は、さまざまな構成を分離できることです。 これにより、プロジェクトビルドの保守性が向上します。

4. 結論

この記事では、さまざまなタイプのテストを分離して実行するためのSurefireプラグインとFailsafeプラグインを比較しました。 また、例を見て、Failsafeプラグインが、さらなるセットアップとクリーンアップを必要とするテストを実行するための追加機能をどのように提供するかを確認しました。

いつものように、コードはGitHubから入手できます。