1概要

MavenはJava分野で最も人気のあるビルドツールですが、統合テストは開発プロセスの重要な部分です。

したがって、Mavenとの統合テストを設定して実行するのは当然の選択です。

このチュートリアルでは、統合テストにMavenを使用し、統合テストと単体テストを分離するためのさまざまな方法について説明します。


2準備

デモンストレーションコードを実際のプロジェクトに近づけるために、JAX-RSアプリケーションを設定します。このアプリケーションは、統合テストの実行前にサーバーにデプロイされ、その後解体されます。


2.1. Mavenの設定

JAX-RSのリファレンス実装であるJerseyを中心にRESTアプリケーションを構築します。この実装にはいくつかの依存関係が必要です。

<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet-core</artifactId>
    <version>2.27</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.inject</groupId>
    <artifactId>jersey-hk2</artifactId>
    <version>2.27</version>
</dependency>


https://search.maven.org/classic/#search%7C1%7Cg%3A%22org.glassfish.jersey.containers%22%20AND%20a%3A%22jersey-これらの依存関係の最新バージョンを見つけることができます。

container-servlet-core%22[ここ]およびhttps://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.glassfish.jersey.inject%22%20AND%20a%3A% 22jersey-hk2%22[ここ]。

テスト環境の設定にはJetty Mavenプラグインを使用します。 ** このプラグインは、Mavenビルドライフサイクルの

pre-integration-test

フェーズ中にJettyサーバーを起動し、その後

post-integration-test

フェーズでそれを停止します。


pom.xml

でJetty Mavenプラグインを設定する方法は次のとおりです。

<plugin>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <version>9.4.11.v20180605</version>
    <configuration>
        <httpConnector>
            <port>8999</port>
        </httpConnector>
        <stopKey>quit</stopKey>
        <stopPort>9000</stopPort>
    </configuration>
    <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>

Jettyサーバーが起動すると、ポート

8999

で待機しています。

stopKey

および

stopPort

設定要素は、プラグインの

stop

目標によってのみ使用され、それらの値は私たちの観点からは重要ではありません。


Here

はどこにありますかJetty Mavenプラグインの最新バージョンを見つけてください。

気をつけるべきもう一つのことは、

pom.xml

ファイルの

packaging

要素を

war

に設定しなければならないことです。

<packaging>war</packaging>


2.2. RESTアプリケーションの作成

アプリケーションエンドポイントは非常に単純です – GETリクエストがコンテキストルートに到達したときにウェルカムメッセージを返す

@Path("/")
public class RestEndpoint {
    @GET
    public String hello() {
        return "Welcome to Baeldung!";
    }
}

これが、エンドポイントクラスをJerseyに登録する方法です。

package com.baeldung.maven.it;

import org.glassfish.jersey.server.ResourceConfig;

public class EndpointConfig extends ResourceConfig {
    public EndpointConfig() {
        register(RestEndpoint.class);
    }
}

JettyサーバーにRESTアプリケーションを認識させるために、古典的な

web.xml

デプロイメント記述子を使用できます。

<web-app
  xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
  http://xmlns.jcp.org/xml/ns/javaee/web-app__3__1.xsd"
  version="3.1">
    <servlet>
        <servlet-name>rest-servlet</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.baeldung.maven.it.EndpointConfig</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>rest-servlet</servlet-name>
        <url-pattern>/** </url-pattern>
    </servlet-mapping>
</web-app>

  • サーバが認識できるように、この記述子は

    /src/main/webapp/WEB-INF

    ** ディレクトリに配置する必要があります。


2.3. クライアント側テストコード

次のセクションのすべてのテストクラスには単一のメソッドが含まれています。

@Test
public void whenSendingGet__thenMessageIsReturned() throws IOException {
    String url = "http://localhost:8999";
    URLConnection connection = new URL(url).openConnection();
    try (InputStream response = connection.getInputStream();
      Scanner scanner = new Scanner(response)) {
        String responseBody = scanner.nextLine();
        assertEquals("Welcome to Baeldung!", responseBody);
    }
}

ご覧のとおり、このメソッドは前に設定したWebアプリケーションにGETリクエストを送信してレスポンスを確認すること以外は何もしません。

** 3統合テストの実際

統合テストに関して注意すべき重要なことは、テストメソッドは実行にかなり長い時間がかかることが多いということです。

そのため、プロジェクトをビルドするたびに統合テストがプロセス全体の速度を落とさないように、デフォルトのビルドライフサイクルから統合テストを除外する必要があります。

  • 統合テストを分ける便利な方法はビルドプロファイルを使用することです** この種の設定は必要な時にだけ適切なプロファイルを指定することによって統合テストを実行することを可能にします。

以降のセクションでは、すべての統合テストをビルドプロファイルで構成します。


4 Failsafeプラグインを使ったテスト

統合テストを実行する最も簡単な方法はhttps://www.baeldung.com/maven-failsafe-plugin[the Maven

failsafe

プラグイン]を使用することです。

デフォルトでは、Mavenの

surefire

プラグインは

test

フェーズの間にユニットテストを実行します。

同封のテストを別々にピックアップするために、これらのプラグインに対して異なるパターンを持つテストクラスに名前を付けることができます。


  • surefire



    failsafe

    で実施されているデフォルトの命名規則は異なります。したがって、単体テストと統合テストを区別するためにこれらの規則に従う必要があります。


surefire

プラグインの実行には、名前が

Test

で始まる、または

Test



Tests

、または

TestCase

で終わるすべてのクラスが含まれます。対照的に、

failsafe

プラグインは、名前が

IT

で始まる、または

IT

または

ITCase

で終わるクラスのテストメソッドを実行します。


ここ

は、

surefire

のテスト組み込みに関するドキュメント、およびhttps://maven.apacheです。 org/surefire/maven-failsafe-plugin/examples/included-exclusion.html[ここ]は

failsafe

用のものです。

デフォルト設定で

failsafe

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

<profile>
    <id>failsafe</id>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>2.22.0</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</profile>

上記の構成では、以下のテストメソッドが

integration-test

フェーズで実行されます。

public class RestIT {
   //test method shown in subsection 2.3
}

Jettyサーバーは

pre-integration-test

フェーズで起動し、

post-integration-test

でシャットダウンするので、今見たテストは次のコマンドで成功します。

mvn verify -Pfailsafe

異なる名前のクラスを含めるように命名パターンをカスタマイズすることもできます。

<plugin>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>2.22.0</version>
    <configuration>
        <includes>
            <include>** ** /** RestIT</include>
            <include>** ** /RestITCase</include>
        </includes>
    </configuration>
    ...
</plugin>


5 Surefireプラグインを使ったテスト


failsafe

プラグインの他に、**


surefire

プラグイン

を使用して、さまざまなフェーズでユニットテストと統合テストを実行することもできます。

すべての統合テストに

IntegrationTest

というサフィックスを付けたいとしましょう。

surefire

プラグインはデフォルトで

test

フェーズでそのような名前でテストを実行するので、デフォルトの実行からそれらを除外する必要があります:

<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.22.0</version>
    <configuration>
        <excludes>
            <exclude>** ** /** IntegrationTest</exclude>
        </excludes>
    </configuration>
</plugin>

このプラグインの最新バージョンはhttps://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.apache.maven.plugins%22%20AND%20a%3A%22maven-surefire-です。プラグイン%22[ここ]。

ビルドライフサイクルから、名前が

IntegrationTest

で終わるすべてのテストクラスを除外しました。プロファイルに戻してみましょう。

<profile>
    <id>surefire</id>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.0</version>
                <executions>
                    <execution>
                        <phase>integration-test</phase>
                        <goals>
                            <goal>test</goal>
                        </goals>
                        <configuration>
                            <excludes>
                                <exclude>none</exclude>
                            </excludes>
                            <includes>
                                <include>** ** /** IntegrationTest</include>
                            </includes>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</profile>

  • いつものように、

    surefire

    プラグインの

    test

    目標を

    test

    ビルド段階にバインドする代わりに、それを

    integration-test

    段階にバインドします。

基本設定で指定された除外を上書きするために

exclude

要素を

none

に設定しなければならないことに注意してください。

それでは、命名パターンを使用して統合テストクラスを定義しましょう。

public class RestIntegrationTest {
   //test method shown in subsection 2.3
}

このテストは次のコマンドで実行されます。

mvn verify -Psurefire


6. 貨物プラグインを使ったテスト

Mavenの

cargoプラグインと一緒に

surefire__プラグインを使用することができます。このプラグインには組み込みサーバーのサポートが組み込まれています。これは統合テストに非常に役立ちます。

この組み合わせの詳細については、https://www.baeldung.com/integration-testing-with-the-maven-cargo-plugin[ここ]を参照してください。

7. JUnitの

@ Category

を使ったテスト

テストを選択的に実行する便利な方法は、JUnit 4フレームワークのhttps://junit.org/junit4/javadoc/latest/org/junit/experimental/categories/Category.html[@

Category

notation]を利用することです。この注釈により、単体テストから特定のテストを除外し、統合テストに含めることができます。

まず、カテゴリ識別子として機能するためのインタフェースまたはクラスが必要です。

package com.baeldung.maven.it;

public interface Integration { }

それから

@ Category

アノテーションと

Integration

識別子でテストクラスを装飾することができます:

@Category(Integration.class)
public class RestJUnitTest {
   //test method shown in subsection 2.3
}

テストクラスで

@ Category

アノテーションを宣言するのではなく、メソッドレベルでそれを使用して個々のテストメソッドを分類することもできます。


test

ビルドフェーズからカテゴリを除外するのは簡単です。

<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.22.0</version>
    <configuration>
        <excludedGroups>com.baeldung.maven.it.Integration</excludedGroups>
    </configuration>
</plugin>


integration-test

フェーズに

Integration

カテゴリを含めることも簡単です。

<profile>
    <id>category</id>
        <build>
        <plugins>
            <plugin>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>2.22.0</version>
                <configuration>
                    <includes>
                        <include>** ** /** </include>
                    </includes>
                    <groups>com.baeldung.maven.it.Integration</groups>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</profile>

これでMavenコマンドを使って統合テストを実行できます。

mvn verify -Pcategory


8統合テスト用に別のディレクトリを追加する

統合テスト用に別のディレクトリを用意することが望ましい場合があります。このようにテストを整理することで、統合テストと単体テストを完全に分離することができます。

この目的のためにMaven

build helper

プラグインを使用することができます。

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <version>3.0.0</version>
    <executions>
        <execution>
            <id>add-integration-test-source</id>
            <phase>generate-test-sources</phase>
            <goals>
                <goal>add-test-source</goal>
            </goals>
            <configuration>
                <sources>
                    <source>src/integration-test/java</source>
                </sources>
            </configuration>
        </execution>
    </executions>
</plugin>


Here

はこのプラグインの最新版はどこにありますか。

今見た設定はビルドにテストソースディレクトリを追加します。新しいディレクトリにクラス定義を追加しましょう。

public class RestITCase {
   //test method shown in subsection 2.3
}

このクラスで統合テストを実行する時が来ました。

mvn verify -Pfailsafe

Maven

failsafe

プラグインは、3.1節で設定した設定により、このテストクラスのメソッドを実行します。

テストソースディレクトリは、しばしばリソースディレクトリと一緒になります。そのようなディレクトリを別の

execution

要素にプラグイン設定に追加することができます。

<executions>
    ...
    <execution>
        <id>add-integration-test-resource</id>
        <phase>generate-test-resources</phase>
        <goals>
            <goal>add-test-resource</goal>
        </goals>
        <configuration>
            <resources>
                <resource>
                    <directory>src/integration-test/resources</directory>
                </resource>
            </resources>
        </configuration>
    </execution>
</executions>


9結論

この記事では、Mavenを使用してJettyサーバーとの統合テストを実行し、Maven

surefire

および

failsafe

プラグインの構成に焦点を当てました。

このチュートリアルの完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/maven[over on GitHub]にあります。