スプリングブート 3。1.0 は、統合テストの記述を容易にするだけでなく、ローカル開発を容易にする Testcontainers の優れたサポートを導入しました。

「Clone & Run」開発者エクスペリエンス
アプリケーションを実行する前にローカルでセットアップするために必要な手動手順の長いリストを含むドキュメントを管理する時代は終わりました。 Dockerがアプリケーションをインストールすることで、依存関係が容易になりました。 しかし、アプリケーションの依存関係をDockerコンテナとして手動でスピンアップするために、オペレーティングシステムに基づいて異なるバージョンのスクリプトを維持する必要がありました。
Spring Boot 3に追加された Testcontainers のサポートにより、 .1.0, 開発者は、リポジトリをクローンしてアプリケーションを実行するだけで済みます。 データベース、メッセージブローカーなどのすべてのアプリケーションの依存関係は、アプリケーションの実行時に自動的に開始するように構成できます。
Testcontainers を初めて使用する場合は、「 Java Spring Boot プロジェクトの Testcontainers 入門 」ガイドを参照して、Testcontainers を使用して Spring Boot アプリケーションをテストする方法を学習してください。
ServiceConnections を使用した統合テストの簡素化
Spring Boot 3より前は .1.0, Testcontainers によって起動されたコンテナーから取得した動的プロパティを次のように設定するために使用する @DynamicPropertySource
必要がありました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | @SpringBootTest (webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @Testcontainers class CustomerControllerTest { @Container static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>( "postgres:15-alpine" ); @DynamicPropertySource static void configureProperties(DynamicPropertyRegistry registry) { registry.add( "spring.datasource.url" , postgres::getJdbcUrl); registry.add( "spring.datasource.username" , postgres::getUsername); registry.add( "spring.datasource.password" , postgres::getPassword); } // your tests } |
次に、Spring Boot 3。1.0 ServiceConnection の新しい概念が導入されました。これにより、サポートするコンテナーに必要な Spring Boot プロパティが自動的に構成されます。
まず、 テスト 依存関係として追加 spring-boot-testcontainers
します。
1 2 3 4 5 | <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-testcontainers</artifactId> <scope>test</scope> </dependency> |
これで、前の例を明示的に設定spring.datasource.url
せずに追加@ServiceConnection
することで書き直すことができます。spring.datasource.username
, そして spring.datasource.password
、その @DynamicPropertySource
アプローチを使用します。
1 2 3 4 5 6 7 8 9 10 11 | @SpringBootTest (webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @Testcontainers class CustomerControllerTest { @Container @ServiceConnection static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>( "postgres:15-alpine" ); // your tests } |
データソースのプロパティを明示的に登録していないことに注意してください。
このサポートは@ServiceConnection
、リレーショナルデータベースだけでなく、Kafka、RabbitMQ、Redis、MongoDB、ElasticSearch、Neo4jなど、一般的に使用される他の多くの依存関係でも機能します。サポートサービスの完全なリストについては、 公式ドキュメントを参照してください。
また、すべてのコンテナーの依存関係を 1 つの TestConfiguration クラスで定義し、それを統合テストにインポートすることもできます。
たとえば、アプリケーションで Postgres と Kafka を使用しているとします。 その後、次のようにという ContainersConfig
クラスを作成できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | @TestConfiguration (proxyBeanMethods = false ) public class ContainersConfig { @Bean @ServiceConnection public PostgreSQLContainer<?> postgreSQLContainer() { return new PostgreSQLContainer<>( "postgres:15.2-alpine" ); } @Bean @ServiceConnection public KafkaContainer kafkaContainer() { return new KafkaContainer( DockerImageName.parse( "confluentinc/cp-kafka:7.2.1" )); } } |
最後に、次のようにテストにインポート ContainersConfig
できます。
1 2 3 4 5 6 | @SpringBootTest (webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @Import (ContainersConfig. class ) class ApplicationTests { //your tests } |
ServiceConnection をサポートしていないコンテナーを使用する方法
アプリケーションでは、専用の Testcontainers モジュールや Spring Boot のすぐに使用できる ServiceConnection サポートがない依存関係を使用する必要がある場合があります。 Testcontainers GenericContainer
を使用して、 を使用してプロパティ DynamicPropertyRegistry
を登録できますので、ご安心ください。
たとえば、電子メール機能のテストに Mailhog を使用できます。 この場合、Testcontainers GenericContainer
を使用して、次のように Spring Boot の電子メール プロパティを登録できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | @TestConfiguration (proxyBeanMethods = false ) public class ContainersConfig { @Bean @ServiceConnection public PostgreSQLContainer<?> postgreSQLContainer() { return new PostgreSQLContainer<>( "postgres:15.2-alpine" ); } @Bean @ServiceConnection public KafkaContainer kafkaContainer() { return new KafkaContainer( DockerImageName.parse( "confluentinc/cp-kafka:7.2.1" )); } @Bean public GenericContainer mailhogContainer(DynamicPropertyRegistry registry) { GenericContainer container = new GenericContainer( "mailhog/mailhog" ) .withExposedPorts( 1025 ); registry.add( "spring.mail.host" , container::getHost); registry.add( "spring.mail.port" , container::getFirstMappedPort); return container; } } |
これまで見てきたように、任意のコンテナー化されたサービスを使用して、アプリケーションのプロパティを登録できます。
Testcontainers を使用したローカル開発
前のセクションでは、Testcontainerを使用してSpring Bootアプリケーションをテストする方法を学びました。 Spring Boot 3を使用します。1.0 Testcontainers のサポートでは、開発時に Testcontainers を使用してアプリケーションをローカルで実行することもできます。
これを行うには、 次のように src/test/java の下のテストクラスパスにクラスを作成します TestApplication 。
1 2 3 4 5 6 7 8 9 10 | import org.springframework.boot.SpringApplication; public class TestApplication { public static void main(String[] args) { SpringApplication .from(Application::main) //Application is main entrypoint class .with(ContainersConfig. class ) .run(args); } } |
構成.with(...)
クラスContainersConfig
を使用して、アプリケーション起動ツールにアタッチしたことを確認します。
これで、IDEから実行できます TestApplication
。 で ContainersConfig
定義されているすべてのコンテナーが自動的に起動され、プロパティが構成されます。
次のように、Maven または Gradle ビルドツールを使用して実行 TestApplication
することもできます。
1 2 | ./mvnw spring-boot:test-run //Maven ./gradlew bootTestRun //Gradle |
開発時に Testcontainers で DevTools を使用する
ここまでで、ローカル開発に Testcontainers を使用する方法を学びました。 ただし、このセットアップの 1 つの課題は、アプリケーションが変更されてビルドがトリガーされるたびに、既存のコンテナーが破棄され、新しいコンテナーが作成されることです。 これにより、アプリケーションの再起動間でデータが遅くなったり、失われたりする可能性があります。
Spring Bootは、コードの変更時にアプリケーションを更新することで開発者エクスペリエンスを向上させるための開発ツールを提供します。 devtools によって提供されるアノテーションを使用して @RestartScope
、特定の Bean を再作成する代わりに再利用することを示すことができます。
まず、 spring-boot-devtools 依存関係を次のように追加しましょう。
1 2 3 4 5 6 7 8 9 10 | <!-- For Maven --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional> true </optional> </dependency> <!-- For Gradle --> testImplementation "org.springframework.boot:spring-boot-devtools" |
次に、次のようにBean定義ContainersConfig
に注釈を追加します@RestartScope
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | @TestConfiguration (proxyBeanMethods = false ) public class ContainersConfig { @Bean @ServiceConnection @RestartScope public PostgreSQLContainer<?> postgreSQLContainer() { return new PostgreSQLContainer<>( "postgres:15.2-alpine" ); } @Bean @ServiceConnection @RestartScope public KafkaContainer kafkaContainer() { return new KafkaContainer( DockerImageName.parse( "confluentinc/cp-kafka:7.2.1" )); } ... } |
これで、アプリケーション コードを変更し、ビルドがトリガーされた場合、アプリケーションは再起動されますが、既存のコンテナーが使用されます。
注意:Eclipseはコードの変更が保存されると自動的にビルドをトリガーしますが、IntelliJ IDEAではビルドを手動でトリガーする必要があります。
結論
最新のソフトウェア開発では、増大するビジネスニーズに対応するために、多くのテクノロジーとツールを使用します。 これにより、開発環境のセットアップが大幅に複雑になりました。 開発者エクスペリエンスの向上は、もはや 「あればいい」 というものではなく、 必要不可欠なものです。
この開発者エクスペリエンスを改善するために、Spring Boot 3.1.0 Testcontainers の標準サポートが追加されました。 Spring Boot と Testcontainers の統合は、ローカルの Docker、CI、 および Testcontainers Cloud でもシームレスに機能します。
これは、テストだけでなく、ローカル開発にも影響を与える変革です。 そして開発者は、 クローン &ランの哲学を現実のものにする体験を期待することができます。
さらに詳しく
- Testcontainers Cloud アカウントにサインアップします。
- Testcontainers Slack で接続します。
- Testcontainers のベスト プラクティスについて学習します。
- Testcontainers ガイドから開始します。
- Docker Newsletter を購読してください。
- 質問がありますか? Docker コミュニティがお手伝いします。
- ドッカーは初めてですか?始めましょう。