JavaテストのDockerテストコンテナ

JavaテストのDockerテストコンテナー

1. 前書き

In this tutorial, we’ll be looking at Java TestContainers library.これにより、テスト内でDockerコンテナーを使用できます。 その結果、外部リソースに依存する自己完結型の統合テストを作成できます。

テストでは、Dockerイメージを持つ任意のリソースを使用できます。 たとえば、データベース、Webブラウザ、Webサーバー、およびメッセージキュー用のイメージがあります。 したがって、テスト内でコンテナとして実行できます。

2. 必要条件

TestContainersライブラリは、Java8以降で使用できます。 また、JUnitルールAPIと互換性があります。

まず、コア機能のMaven依存関係を定義しましょう。


    org.testcontainers
    testcontainers
    1.11.4

専用コンテナ用のモジュールもあります。 このチュートリアルでは、PostgreSQL Selenium. を使用します

関連する依存関係を追加しましょう:


    org.testcontainers
    postgresql 
    1.11.4


    org.testcontainers
    selenium 
    1.11.4

Maven Centralで最新バージョンを見つけることができます。

Also, we need Docker to run containers。 インストール手順については、Docker documentationを参照してください。

テスト環境でDockerコンテナを実行できることを確認してください。

3. 使用法

一般的なコンテナルールを設定しましょう。

@ClassRule
public static GenericContainer simpleWebServer
 = new GenericContainer("alpine:3.2")
   .withExposedPorts(80)
   .withCommand("/bin/sh", "-c", "while true; do echo "
     + "\"HTTP/1.1 200 OK\n\nHello World!\" | nc -l -p 80; done");

Dockerイメージ名を指定して、GenericContainerテストルールを作成します。 次に、ビルダーメソッドで構成します。

  • withExposedPorts を使用して、コンテナからポートを公開します

  • withCommandはコンテナコマンドを定義する。 コンテナの起動時に実行されます。

ルールには@ClassRule. アノテーションが付けられます。その結果、そのクラスのテストが実行される前にDockerコンテナが開始されます.すべてのメソッドが実行された後、コンテナは破棄されます。

@Ruleアノテーションを適用すると、GenericContainerルールが各テストメソッドの新しいコンテナを開始します。 そして、そのテストメソッドが終了するとコンテナを停止します。

We can use IP address and port to communicate with the process running in the container

@Test
public void givenSimpleWebServerContainer_whenGetReuqest_thenReturnsResponse()
  throws Exception {
    String address = "http://"
      + simpleWebServer.getContainerIpAddress()
      + ":" + simpleWebServer.getMappedPort(80);
    String response = simpleGetRequest(address);

    assertEquals(response, "Hello World!");
}

4. 使用モード

テストコンテナにはいくつかのusage modesがあります。 GenericContainer.を実行する例を見ました

TestContainersライブラリには、特殊な機能を備えたルール定義もあります。 これらは、MySQL、PostgreSQLなどの一般的なデータベースのコンテナ用です。 Webクライアントなど。

これらを汎用コンテナとして実行できますが、特殊化により便利なメソッドが拡張されます。

4.1. データベース

データアクセス層統合テスト用のデータベースサーバーが必要であると仮定しましょう。 TestContainersライブラリの助けを借りて、コンテナでデータベースを実行できます。

たとえば、PostgreSQLContainerルールを使用してPostgreSQLコンテナを起動します。 その後、ヘルパーメソッドを使用できるようになります。 These are getJdbcUrl, getUsername, getPassword for database connection:

@Rule
public PostgreSQLContainer postgresContainer = new PostgreSQLContainer();

@Test
public void whenSelectQueryExecuted_thenResulstsReturned()
  throws Exception {
    String jdbcUrl = postgresContainer.getJdbcUrl();
    String username = postgresContainer.getUsername();
    String password = postgresContainer.getPassword();
    Connection conn = DriverManager
      .getConnection(jdbcUrl, username, password);
    ResultSet resultSet =
      conn.createStatement().executeQuery("SELECT 1");
    resultSet.next();
    int result = resultSet.getInt(1);

    assertEquals(1, result);
}

PostgreSQLを汎用コンテナとして実行することもできます。 ただし、接続を構成するのはもっと難しいでしょう。

4.2. Webドライバー

別の便利なシナリオは、Webブラウザーでコンテナーを実行することです。 BrowserWebDriverContainer ruleは、Chrome およびFirefox indocker-selenium containersの実行を有効にします。 次に、それらをRemoteWebDriver. で管理します

これは、WebアプリケーションのUI /受け入れテストを自動化するのに非常に役立ちます。

@Rule
public BrowserWebDriverContainer chrome = new BrowserWebDriverContainer()
  .withCapabilities(new ChromeOptions());
@Test
public void whenNavigatedToPage_thenHeadingIsInThePage() {
    RemoteWebDriver driver = chrome.getWebDriver();
    driver.get("http://example.com");
    String heading = driver.findElement(By.xpath("/html/body/div/h1"))
      .getText();

    assertEquals("Example Domain", heading);
}

4.3. Docker Compose

テストでより複雑なサービスが必要な場合は、docker-composeファイルで指定できます。

simpleWebServer:
  image: alpine:3.2
  command: ["/bin/sh", "-c", "while true; do echo 'HTTP/1.1 200 OK\n\nHello World!' | nc -l -p 80; done"]

次に、DockerComposeContainerルールを使用します。 このルールは、作成ファイルで定義されたサービスを開始および実行します。

getServiceHostメソッドとgetServicePostメソッドを使用して、サービスへの接続アドレスを構築します。

@ClassRule
public static DockerComposeContainer compose =
  new DockerComposeContainer(
    new File("src/test/resources/test-compose.yml"))
      .withExposedService("simpleWebServer_1", 80);

@Test
public void givenSimpleWebServerContainer_whenGetReuqest_thenReturnsResponse()
  throws Exception {

    String address = "http://" + compose.getServiceHost("simpleWebServer_1", 80) + ":" + compose.getServicePort("simpleWebServer_1", 80);
    String response = simpleGetRequest(address);

    assertEquals(response, "Hello World");
}

5. 結論

TestContainersライブラリをどのように使用できるかを見ました。 統合テストの開発と実行が容易になります。

特定のDockerイメージのコンテナにGenericContainer ruleを使用しました。 次に、PostgreSQLContainer, BrowserWebDriverContainerDockerComposeContainerのルールを確認しました。 特定のユースケースに対してより多くの機能を提供します。

最後に、ここのコードサンプルはover on GitHubにあります。