Mavenとの統合テスト

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

これらの依存関係の最新バージョンhereおよびhereを見つけることができます。

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でリッスンします。 stopKeystopPortの構成要素は、プラグインの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は実行します。

含まれるテストを個別に取得するために、これらのプラグインのさまざまなパターンでテストクラスに名前を付けることができます。

surefirefailsafeによって適用されるデフォルトの命名規則は異なるため、ユニットテストと統合テストを分離するには、これらの規則に従う必要があります。

surefireプラグインの実行には、名前がTestで始まるか、TestTests、またはTestCaseで終わるすべてのクラスが含まれます。 対照的に、failsafeプラグインは、名前がITで始まるか、ITまたはITCaseで終わるクラスでテストメソッドを実行します。

Thisは、surefireのテストの包含に関するドキュメントを見つけることができる場所であり、herefailsafeのドキュメントです。

デフォルト設定で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にあります。