Testcontainers Desktop を使用した Testcontainers サービスへの接続

Testcontainers Desktopアプリは、オープンソースのTestcontainersライブラリの無料のコンパニオンアプリで、実際の依存関係を使用したローカル開発とテストを簡単にします。

Testcontainers Desktop アプリが提供するさまざまな機能については、 Testcontainers Desktop のドキュメント を参照してください。 この記事では、お気に入りのデータベースクライアントツールからTestcontainersによって開始されたデータベースに接続する方法を学びます。

testcontainers デスクトップを使用して testcontainers サービスに接続するバナー

Docker DesktopやOrbStackなどのコンテナランタイムを使用してコンテナをローカルで実行する場合でも、Testcontainers Cloudを使用してクラウド上で実行する場合でも、Testcontainers Desktopのポートフォワーディング機能を使用して、データベースやメッセージブローカーなどのコンテナ化されたサービスに接続できます。

各サービスが独自のデータベースを持つマイクロサービスベースのアプリケーションで作業している場合があります。 また、複数のマイクロサービスを実行し、複数のデータベースに接続してデータを検査することもできます。

このブログ記事では、Testcontainers Desktopのポートフォワーディング機能を使用して、同じタイプの複数のコンテナ(PostgreSQLなど)に接続する方法をご紹介します。

2つのSpring Bootマイクロサービス(product-serviceとpromotion-service)があり、PostgreSQLをデータベースとして使用しているとします。 Spring BootのTestcontainersサポートを使用して、両方のサービスのPostgreSQLコンテナを起動できます。次に、Testcontainers Desktopのポート転送機能を使用して、Testcontainersによって作成されたデータベースに接続する方法を学習します。

この記事のソース コードは GitHub にあります。 

製品サービスの作成

Spring Initializr を使用して製品サービスを作成するには、Spring Web、Spring Data JPA、Flyway Migration、PostgreSQL Drive、および Testcontainers スターターを選択します。

生成されたプロジェクトでは、次のようにsrc/test/javaの下にTestProductServiceApplication.javaが表示されます。

package com.testcontainers.products;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.context.annotation.Bean;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.utility.DockerImageName;
@TestConfiguration(proxyBeanMethods = false)
public class TestProductServiceApplication {
  @Bean
  @ServiceConnection
  PostgreSQLContainer<?> postgresContainer() {
      return new PostgreSQLContainer<>(DockerImageName.parse("postgres:16-alpine"));
  }
  public static void main(String[] args) {
      SpringApplication
              .from(ProductServiceApplication::main)
              .with(TestProductServiceApplication.class)
              .run(args);
  }
}

これで、IDE から TestProductServiceApplication.java を実行してアプリケーションを起動できます。 Testcontainers を使用して PostgreSQL データベースコンテナを起動し、そのデータベースを使用するようにアプリケーションを設定し、Flyway を使用してデータベース移行スクリプトを適用します。

製品サービス・データベースへの接続

Testcontainers が PostgreSQL データベース コンテナを起動すると、データベース コンテナのポート 5432 がホスト上のランダムな利用可能なポートにマップされます。 そのため、データベースコンテナのマッピングされたポートが何であるかを毎回確認してから接続するのは面倒です。 代わりに、Testcontainers Desktop のポート転送機能を使用して、コンテナのポートをホスト上の固定ポートにマッピングし、それに接続できます。

[Testcontainers Desktop] を選択し> [サービス] > [構成の場所を開く] を選択します。開いたディレクトリには、 postgres.toml.example ファイルがあるはずです。

この名前を [ products-postgres.toml ファイル] に変更し、次の構成に更新します。

ports = [
  {local-port = 15432, container-port = 5432},
]
selector.image-names = ["postgres"]

上記の構成では、コンテナのポート 5432 をホストのポート 15432にマッピングしています。 

これで、アプリケーションを再起動すると、次の詳細を使用してデータベースに接続できるようになります。

host: localhost
port: 15432
database: test
username: test
password: test

同じ種類の複数のコンテナへの接続

さて、PostgreSQLをデータベースとして使用する別のマイクロサービス、たとえばpromotion-serviceがある場合はどうなるかと思われるかもしれません。

前のポートフォワーディング設定では、イメージセレクタを postgresとして設定しただけで、これは任意のPostgreSQLコンテナと一致します。 そのため、promotion-service を開始すると、product-service と同じポート マッピングも使用されます。 ここで、ラベルセレクターが登場します。

ラベルセレクターの使用

次のように TestProductServiceApplication.java のPostgreSQLコンテナ設定を更新しましょう。

@Bean
@ServiceConnection
PostgreSQLContainer<?> postgresContainer() {
  return new PostgreSQLContainer<>(
          DockerImageName.parse("postgres:16-alpine"))
          .withLabel("com.testcontainers.desktop.service", "products-postgres");
}

コンテナに products-postgres という値を持つラベル com.testcontainers.desktop.serviceを追加しました。これで、このラベルに一致するように products-postgres.toml ファイル内のポート転送設定を更新できます。

ports = [
{local-port = 15432, container-port = 5432},
]
selector.image-names = ["postgres"]
[selector.labels]
"com.testcontainers.desktop.service" = "products-postgres"

画像セレクターに加えて、ラベル com.testcontainers.desktop.service と値 products-postgres を一致させるラベル セレクターを追加しました。

ここで、product-service と同様に PostgreSQL を使用する promotion-service を作成し、次のように src/test/java の下にTestPromotionServiceApplication.javaしたとします。

package com.testcontainers.promotions;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.context.annotation.Bean;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.utility.DockerImageName;
@TestConfiguration(proxyBeanMethods = false)
public class TestPromotionServiceApplication {
  @Bean
  @ServiceConnection
  PostgreSQLContainer<?> postgresContainer() {
      return new PostgreSQLContainer<>(
              DockerImageName.parse("postgres:16-alpine"))
              .withLabel("com.testcontainers.desktop.service", "promotion-postgres");
  }
  public static void main(String[] args) {
      SpringApplication
              .from(PromotionServiceApplication::main)
              .with(TestPromotionServiceApplication.class)
              .run(args);
  }
}

これで、次の構成でproducts-postgres.tomlファイルの横にpromotion-postgres.tomlファイルを作成できます。

ports = [
{local-port = 25432, container-port = 5432},
]
selector.image-names = ["postgres"]
[selector.labels]
"com.testcontainers.desktop.service" = "promotion-postgres"

上記の構成では、コンテナのポート 5432 をホストのポート 25432にマッピングしています。 

これで、promotion-service アプリケーションを開始すると、次の詳細を使用して promotion-service データベースに接続できるようになります。

host: localhost
port: 25432
database: test
username: test
password: test

PostgreSQLデータベースコンテナへの接続を示しましたが、Kafka、RabbitMQ、MongoDBなどの他のコンテナでも同じアプローチが機能します。

概要

Testcontainers Desktopのポートフォワーディング機能を現実的なシナリオで検討しました。 Java/Spring Boot の例を使用して Testcontainers Desktop 機能の使用方法を示しましたが、他の Testcontainers がサポートする言語 (Go、.NET、Node.js、 Pythonなど)も同様です。

Testcontainers Desktop アプリケーションをダウンロードして、アプリケーションのローカル開発とテストに使用を開始できます。

さらに詳しく