0Pricing
Java Academy · レッスン

Testcontainers:実データベースによる統合テスト

TestcontainersでDocker上にPostgreSQLを起動し、実際のデータベースに対して統合テストを実行します。

「Testcontainers:実データベースによる統合テスト」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。

Testcontainers を使う理由

H2 のインメモリデータベースは、PostgreSQL 固有の機能(JSON、全文検索、ON CONFLICT)をサポートしていません。Testcontainers はテスト中に実際の Docker コンテナを起動するため、本番環境と同一のデータベースを使用できます。

Testcontainers の依存関係を追加する

ビルドファイルに Testcontainers BOM と PostgreSQL モジュールを追加します。Spring Boot 3.1 以降には、管理対象の Testcontainers バージョンが含まれています。

// build.gradle:
testImplementation "org.testcontainers:junit-jupiter"
testImplementation "org.testcontainers:postgresql"
// Optionally use Spring Boot Testcontainers support:
testImplementation "org.springframework.boot:spring-boot-testcontainers"

@Testcontainers と @Container

テストクラスに @Testcontainers を付け、コンテナを static な @Container フィールドとして宣言します。JUnit 5 がコンテナを自動的に起動および停止します。

@Testcontainers
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class UserRepositoryIntegrationTest {
    @Container
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine")
        .withDatabaseName("testdb")
        .withUsername("test")
        .withPassword("test");
}

コンテナから DataSource を設定する

@DynamicPropertySource を使用して、コンテナの動的なポートと認証情報を Spring の DataSource 設定に注入します。

@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);
}

Spring Boot 3.1 の ServiceConnection

Spring Boot 3.1 以降では、@ServiceConnection が付与された Testcontainers の @Container Bean から DataSource が自動構成されるため、@DynamicPropertySource は必要ありません。

@Bean
@ServiceConnection
static PostgreSQLContainer<?> postgresContainer() {
    return new PostgreSQLContainer<>("postgres:16-alpine");
}

シングルトンコンテナパターン

テストクラスごとにコンテナを起動すると時間がかかります。Startables.deepStart() を使用する static フィールド、または抽象基底クラスによって、すべてのテストで 1 つのコンテナを共有します。

abstract class AbstractIntegrationTest {
    @Container
    static final PostgreSQLContainer<?> POSTGRES =
        new PostgreSQLContainer<>("postgres:16-alpine").withReuse(true);
    static { POSTGRES.start(); }
    @DynamicPropertySource
    static void props(DynamicPropertyRegistry r) {
        r.add("spring.datasource.url",      POSTGRES::getJdbcUrl);
        r.add("spring.datasource.username", POSTGRES::getUsername);
        r.add("spring.datasource.password", POSTGRES::getPassword);
    }
}

PostgreSQL 固有機能のテスト

Testcontainers を使用すると、JSON カラム、JSONB 演算子、全文検索、ON CONFLICT DO UPDATE をテストできます。これらは H2 では実現できません。

@Test
void jsonb_search_works() {
    // Insert row with JSONB column, then query
    List<Event> logins = repo.findByType("login");
    assertEquals(1, logins.size());
}

複数コンテナ: Compose

複数のサービスを必要とする統合テストでは、DockerComposeContainer を使用して完全なスタック(Postgres + Redis + Kafka)を実行します。

@Container
static DockerComposeContainer<?> compose = new DockerComposeContainer<>(
    new File("src/test/resources/docker-compose.yml"))
    .withExposedService("postgres", 5432)
    .withExposedService("redis", 6379);

Ryuk: 自動クリーンアップ

Testcontainers は Ryuk コンテナを使用して、JVM の終了時にコンテナを自動的に停止・削除します。テストが失敗した場合でも実行されるため、コンテナの残留を防止できます。

Testcontainers での @SpringBootTest

実際の Postgres コンテナに対してアプリケーション全体のスタック(コントローラー、サービス、リポジトリ)をテストするには、@DataJpaTest ではなく @SpringBootTest を使用します。

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Testcontainers
class FullIntegrationTest extends AbstractIntegrationTest {
    @LocalServerPort int port;
    @Autowired TestRestTemplate rest;
    @Test
    void end_to_end_user_creation() {
        ResponseEntity<UserDto> r = rest.postForEntity("/api/users", createReq(), UserDto.class);
        assertEquals(HttpStatus.CREATED, r.getStatusCode());
    }
}

コンテナイメージのキャッシュ

Testcontainers は取得した Docker イメージをローカルにキャッシュします。テスト実行中のダウンロード時間を避けるため、テストの開始前に CI でイメージを取得します(docker pull postgres:16-alpine)。

確認問題

Spring Boot 3.1 以降で、Testcontainers のコンテナを Spring の DataSource に自動接続するアノテーションはどれですか。

まとめ

Testcontainers は統合テスト用に実際の Docker コンテナを実行します。@Container と @DynamicPropertySource、または @ServiceConnection(Boot 3.1 以降)を使用します。シングルトンパターンでテスト間のコンテナを共有します。H2 では実現できない PostgreSQL 固有の機能をテストできます。

よくある質問

「Testcontainers:実データベースによる統合テスト」レッスンは無料ですか?

はい。「Testcontainers:実データベースによる統合テスト」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。

「Testcontainers:実データベースによる統合テスト」で何を学びますか?

TestcontainersでDocker上にPostgreSQLを起動し、実際のデータベースに対して統合テストを実行します。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Java Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「Testcontainers:実データベースによる統合テスト」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このJava Academyレッスンでコードを書いて実行できますか?

はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. @CsvSourceと@MethodSourceによるパラメータ化テスト
  2. Mockito応用:ArgumentCaptorとスパイ
  3. Spring Bootテストスライス:@WebMvcTestと@DataJpaTest
  4. Testcontainers:実データベースによる統合テスト
← Java Academyに戻る