🐈⬛
Spring Boot ・Testcontainers・Flyway でテスト環境を作成
Testcontainersを使用すると、Dockerコンテナ上でデータベースやミドルウェアを立ち上げてテストを行えます。Spring BootアプリケーションにPostgreSQLとFlywayを組み合わせて、テストを行います。
環境
- Java21
- Spring Boot 3.4.4
依存関係
dependencies {
implementation("org.springframework.boot:spring-boot-starter:3.4.4")
implementation("org.springframework.boot:spring-boot-starter-jdbc:3.4.4")
runtimeOnly("org.postgresql:postgresql:42.7.5")
implementation("org.flywaydb:flyway-database-postgresql:11.7.2")
testImplementation("org.springframework.boot:spring-boot-starter-test:3.4.4")
testImplementation("org.springframework.boot:spring-boot-testcontainers:3.4.4")
testImplementation("org.testcontainers:postgresql:1.20.6")
}
プロジェクト構成
構成
src/
├── main/
│ └── java/
│ └── com/
│ └── example/
│ └── Application.java
├── test/
│ ├── java/
│ │ └── com/
│ │ └── example/
│ │ ├── ExampleTest.java
│ │ └── TestContainersConfiguration.java
│ └── resources/
│ └── db/
│ └── migration/
│ └── V00__init.sql
アプリケーション
Application.java
Application.java
package org.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Spring Bootアプリケーションのエントリーポイントです。
ExampleTest.java
ExampleTest.java
package org.example;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
@SpringBootTest
@Import(TestContainersConfiguration.class)
public class ExampleTest {
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
void test() {
List<String> names = jdbcTemplate.queryForList("select name from test order by id", String.class);
Assertions.assertEquals(3, names.size());
Assertions.assertEquals("テスト1", names.get(0));
Assertions.assertEquals("テスト2", names.get(1));
Assertions.assertEquals("テスト3", names.get(2));
}
}
このテストクラスはSpring Bootのテストコンテキストを使って、Testcontainersで起動したPostgreSQLに対してSQLを実行しています。
- @Import(TestContainersConfiguration.class)で、テスト用のDB設定を読み込みます
- JdbcTemplateを使ってSQLを直接発行しています
- Flywayによって初期データが投入されるため実データでのテストが可能です
TestContainersConfiguration.java
TestContainersConfiguration.java
package org.example;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.utility.DockerImageName;
@TestConfiguration(proxyBeanMethods = false)
public class TestContainersConfiguration {
@Bean
@ServiceConnection
PostgreSQLContainer<?> postgres() {
return new PostgreSQLContainer<>(DockerImageName.parse("postgres:17.4"));
}
@DynamicPropertySource
void properties(DynamicPropertyRegistry registry) {
registry.add("spring.flyway.enabled", () -> "true");
}
}
このクラスは、Spring Bootテスト環境でPostgreSQLコンテナを起動し、Springアプリケーションと自動的に接続する設定です。
- @ServiceConnectionを使うことでspring.datasource.*の設定が不要になります
- @DynamicPropertySourceにより、Flywayの自動マイグレーションを有効化しています
初期データ
V00__init.sql
V00__init.sql
create table test (
id integer generated always as identity primary key,
name text
);
insert into test (name) values('テスト1');
insert into test (name) values('テスト2');
insert into test (name) values('テスト3');
Flywayが実行するSQLファイルです。テストを実行すると、ここに記述されている内容がPostgreSQLに反映されます。
実行結果ログ抜粋
TestcontainersがDockerと接続
Connected to docker:
Server Version: 27.4.0
API Version: 1.47
PostgreSQLコンテナが起動
Container is started (JDBC URL: jdbc:postgresql://localhost:52965/test)
Flywayによるマイグレーション
Migrating schema "public" to version "00 - init"
Successfully applied 1 migration to schema "public", now at version v00 (execution time 00:00.005s)
まとめ
Spring Boot、Testcontaners、Flywayを使用して以下のことが実行できました。
- DockerベースのPostgreSQLを使ってテスト
- Flywayでマイグレーション
- @ServiceConnectionを使用してPostgreSQLへ接続
Discussion