1.はじめに

  • このチュートリアルでは、Javaの

    TestContainers

    ライブラリを見ていきます。** テストでDockerコンテナを使用することができます。その結果、外部リソースに依存する自己完結型の統合テストを書くことができます。

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

2.要件


TestContainers

ライブラリは、Java 8以降で使用できます。その上、それはJUnit Rules APIと互換性があります。

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

<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>testcontainers</artifactId>
    <version>1.8.0</version>
</dependency>

特殊コンテナ用のモジュールもあります。このチュートリアルでは、


_ PostgreSQL




Seleniumを使用します。 _

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

<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>postgresql </artifactId>
    <version>1.8.0</version>
</dependency>
<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>selenium </artifactId>
    <version>1.8.0</version>
</dependency>

最新版はhttps://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.testcontainers%22%20AND%20a%3A%22testcontainers%22[Maven Central]でご覧になれます。

  • また、コンテナを実行するにはDockerが必要です** 。インストール方法についてはhttps://docs.docker.com/install/[Dockerのドキュメント]を参照してください。

テスト環境で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 image nameを指定して、

GenericContainer

テストルールを作成します。それから、ビルダーメソッドでそれを設定します。

  • コンテナからポートを公開するために

    __withExposedPorts

    __を使います


  • withCommand

    はコンテナコマンドを定義します。それはいつ実行されます

コンテナが起動します。

このルールには

__ @ ClassRuleという注釈が付けられています。その結果、そのクラスのテストが実行される前にDockerコンテナーが開始されます。


.

__すべてのメソッドが実行された後でコンテナーは破棄されます。


@ Rule

アノテーションを適用すると、

GenericContainer

ruleはテストメソッドごとに新しいコンテナを開始します。そしてそのテストメソッドが終了したらコンテナを停止します。

  • コンテナ内で実行されているプロセスと通信するためにIPアドレスとポートを使用できます。

@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.使用モード

テストコンテナにはいくつかの使用モードがあります。 __GenericContainerを実行する例を見ました。


TestContainers

ライブラリには、特殊な機能を持つルール定義もあります。それらはMySQL、PostgreSQLのような一般的なデータベースのコンテナ用です。そしてWebクライアントが好きな人もいます。

汎用コンテナとして実行することはできますが、特殊化によって拡張された便利なメソッドが提供されます。

4.1. データベース

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

たとえば、PostgreSQLコンテナを

PostgreSQLContainer

ルールで起動します。それから、ヘルパーメソッドを使用することができます。

  • データベース接続用の

    getJdbcUrl、getUsername、getPassword

    です。

@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ドライバ

もう1つの便利なシナリオは、Webブラウザでコンテナを実行することです。

__BrowserWebDriverContainer


ruleは


Chrome





Firefox


in


docker-selenium

__containersの実行を可能にします。

それから、

RemoteWebDriverでそれらを管理します。

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

@Rule
public BrowserWebDriverContainer chrome
  = new BrowserWebDriverContainer()
    .withDesiredCapabilities(DesiredCapabilities.chrome());

@Test
public void whenNavigatedToPage__thenHeadingIsInThePage() {
    RemoteWebDriver driver = chrome.getWebDriver();
    driver.get("https://saucelabs.com/test/guinea-pig");
    String heading = driver
      .findElement(By.xpath("/html/body/h1")).getText();

    assertEquals("This page is a Selenium sandbox", 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__メソッドを使います

[source,java,gutter:,true]

@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、BrowserWebDriverContainer__、および__DockerComposeContainer__ルールを調べました。それらは特定のユースケースに対してより多くの機能を与えます。

最後に、ここにあるコードサンプルはhttps://github.com/eugenp/tutorials/tree/master/testing-modules/test-containers[GitHubに載っています]。