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, BrowserWebDriverContainerとDockerComposeContainerのルールを確認しました。 特定のユースケースに対してより多くの機能を提供します。
最後に、ここのコードサンプルはover on GitHubにあります。