Mavenとの統合テスト
1. 概要
MavenはJava空間で最も人気のあるビルドツールであり、統合テストは開発プロセスの重要な部分です。 したがって、it’s a natural choice to configure and execute integration tests with Maven.
このチュートリアルでは、統合テストにMavenを使用し、統合テストを単体テストから分離するためのさまざまな方法について説明します。
2. 準備
デモコードを実際のプロジェクトに近づけるために、JAX-RSアプリケーションをセットアップします。 このアプリケーションは、統合テストの実行前にサーバーにデプロイされ、その後解体されます。
2.1. Mavenの構成
JAX-RSのリファレンス実装であるJerseyを中心にRESTアプリケーションを構築します。 この実装には、いくつかの依存関係が必要です。
org.glassfish.jersey.containers
jersey-container-servlet-core
2.27
org.glassfish.jersey.inject
jersey-hk2
2.27
JettyMavenプラグインを使用してテスト環境をセットアップします。 This plugin starts a Jetty server during the pre-integration-test phase of the Maven build lifecycle, then stops it in the post-integration-test phase.
Jetty Mavenプラグインをpom.xmlで構成する方法は次のとおりです。
org.eclipse.jetty
jetty-maven-plugin
9.4.11.v20180605
8999
quit
9000
start-jetty
pre-integration-test
start
stop-jetty
post-integration-test
stop
Jettyサーバーが起動すると、ポート8999でリッスンします。 stopKeyとstopPortの構成要素は、プラグインのstopの目標によってのみ使用され、それらの値は私たちの観点からは重要ではありません。
Hereは、JettyMavenプラグインの最新バージョンを見つける場所です。
もう1つの注意点は、pom.xmlファイルのpackaging要素をwarに設定する必要があることです。そうしないと、Jettyプラグインはサーバーを起動できません。
war
2.2. RESTアプリケーションの作成
アプリケーションエンドポイントは非常に単純です。GETリクエストがコンテキストルートに到達すると、ウェルカムメッセージを返します。
@Path("/")
public class RestEndpoint {
@GET
public String hello() {
return "Welcome to example!";
}
}
これは、エンドポイントクラスをJerseyに登録する方法です。
package com.example.maven.it;
import org.glassfish.jersey.server.ResourceConfig;
public class EndpointConfig extends ResourceConfig {
public EndpointConfig() {
register(RestEndpoint.class);
}
}
JettyサーバーにRESTアプリケーションを認識させるために、従来のweb.xmlデプロイメント記述子を使用できます。
rest-servlet
org.glassfish.jersey.servlet.ServletContainer
javax.ws.rs.Application
com.example.maven.it.EndpointConfig
rest-servlet
/*
This descriptor must be placed in the directory /src/main/webapp/WEB-INFはサーバーによって認識されます。
2.3. クライアント側のテストコード
以下のセクションのすべてのテストクラスには、1つのメソッドが含まれています。
@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 example!", responseBody);
}
}
ご覧のように、このメソッドは、前に設定したWebアプリケーションにGETリクエストを送信し、応答を確認するだけです。
3. 実際の統合テスト
統合テストについて注意すべき重要なことは、test methods often take quite a long time to run.
そのため、デフォルトのビルドライフサイクルから統合テストを除外し、プロジェクトをビルドするたびにプロセス全体の速度が低下しないようにする必要があります。
A convenient way to separate integration tests is to use build profiles.この種の構成では、適切なプロファイルを指定することにより、必要な場合にのみ統合テストを実行できます。
次のセクションでは、ビルドプロファイルを使用してすべての統合テストを構成します。
4. フェイルセーフプラグインを使用したテスト
統合テストを実行する最も簡単な方法は、the Maven failsafe pluginを使用することです。
デフォルトでは、Mavensurefireプラグインはtestフェーズ中に単体テストを実行し、the failsafe plugin runs integration tests in the integration-test phaseは実行します。
含まれるテストを個別に取得するために、これらのプラグインのさまざまなパターンでテストクラスに名前を付けることができます。
surefireとfailsafeによって適用されるデフォルトの命名規則は異なるため、ユニットテストと統合テストを分離するには、これらの規則に従う必要があります。
surefireプラグインの実行には、名前がTestで始まるか、Test、Tests、またはTestCaseで終わるすべてのクラスが含まれます。 対照的に、failsafeプラグインは、名前がITで始まるか、ITまたはITCaseで終わるクラスでテストメソッドを実行します。
デフォルト設定でfailsafeプラグインをPOMに追加しましょう:
failsafe
maven-failsafe-plugin
2.22.0
integration-test
verify
This linkは、failsafeプラグインの最新バージョンを見つける場所です。
上記の構成では、次のテストメソッドがintegration-testフェーズで実行されます。
public class RestIT {
// test method shown in subsection 2.3
}
Jettyサーバーはpre-integration-testフェーズで起動し、post-integration-testでシャットダウンするため、今見たテストは次のコマンドで合格します。
mvn verify -Pfailsafe
命名パターンをカスタマイズして、異なる名前のクラスを含めることもできます。
maven-failsafe-plugin
2.22.0
**/*RestIT
**/RestITCase
...
5. Surefireプラグインを使用したテスト
failsafeプラグインとは別に、we can also use the surefire plugin to execute unit and integration tests in different phases.
すべての統合テストに接尾辞IntegrationTestを付けたいとしましょう。 surefireプラグインは、デフォルトでtestフェーズでそのような名前でテストを実行するため、デフォルトの実行からそれらを除外する必要があります。
maven-surefire-plugin
2.22.0
**/*IntegrationTest
このプラグインの最新バージョンはhereです。
名前がIntegrationTestで終わるすべてのテストクラスをビルドライフサイクルから除外しました。 プロフィールでそれらを元に戻す時が来ました:
surefire
maven-surefire-plugin
2.22.0
integration-test
test
none
**/*IntegrationTest
Instead of binding the test goal of the surefire plugin to the test build phase, as usual, we bound it to the integration-test phase.プラグインは、統合テストプロセス中に起動します。
基本構成で指定された除外をオーバーライドするには、exclude要素をnoneに設定する必要があることに注意してください。
それでは、名前付けパターンを使用して統合テストクラスを定義しましょう。
public class RestIntegrationTest {
// test method shown in subsection 2.3
}
このテストは次のコマンドで実行されます:
mvn verify -Psurefire
6. Cargoプラグインを使用したテスト
surefireプラグインをMavencargoプラグインと一緒に使用できます。 このプラグインには組み込みサーバーのサポートが組み込まれているため、統合テストに非常に役立ちます。
この組み合わせの詳細については、hereをご覧ください。
7. JUnitの@Categoryを使用したテスト
テストを選択的に実行する便利な方法は、JUnit 4フレームワークでthe @Category annotationを活用することです。 This annotation lets us exclude particular tests from unit testing, and include them in integration testing.
まず、カテゴリ識別子として機能するインターフェイスまたはクラスが必要です。
package com.example.maven.it;
public interface Integration { }
次に、@CategoryアノテーションとIntegration識別子でテストクラスを装飾できます。
@Category(Integration.class)
public class RestJUnitTest {
// test method shown in subsection 2.3
}
テストクラスで@Categoryアノテーションを宣言するのではなく、メソッドレベルで使用して、個々のテストメソッドを分類することもできます。
testのビルドフェーズからカテゴリを除外するのは簡単です。
maven-surefire-plugin
2.22.0
com.example.maven.it.Integration
integration-testフェーズにIntegrationカテゴリを含めることも簡単です。
category
maven-failsafe-plugin
2.22.0
**/*
com.example.maven.it.Integration
integration-test
verify
Mavenコマンドを使用して統合テストを実行できるようになりました。
mvn verify -Pcategory
8. 統合テスト用に別のディレクトリを追加する
統合テスト用に別のディレクトリを用意することが望ましい場合があります。 Organizing tests this way allows us to entirely isolate integration tests from unit tests.
この目的のためにMavenbuild helperプラグインを使用できます。
org.codehaus.mojo
build-helper-maven-plugin
3.0.0
add-integration-test-source
generate-test-sources
add-test-source
src/integration-test/java
Hereは、このプラグインの最新バージョンを見つけることができる場所です。
今見た構成では、テストソースディレクトリがビルドに追加されます。 その新しいディレクトリにクラス定義を追加しましょう。
public class RestITCase {
// test method shown in subsection 2.3
}
このクラスで統合テストを実行するときが来ました。
mvn verify -Pfailsafe
Mavenfailsafeプラグインは、サブセクション3.1で設定した構成により、このテストクラスのメソッドを実行します。
多くの場合、テストソースディレクトリにはリソースディレクトリが含まれます。 このようなディレクトリを別のexecution要素にプラグイン構成に追加できます。
...
add-integration-test-resource
generate-test-resources
add-test-resource
src/integration-test/resources
9. 結論
この記事では、Mavenを使用してJettyサーバーとの統合テストを実行し、Mavensurefireおよびfailsafeプラグインの構成に焦点を当てました。
このチュートリアルの完全なソースコードはover on GitHubにあります。