Kotestテストコンテナ(Testcontainers)拡張

Testcontainersは、テスト時にコンテナベースの外部リソースを使用できるようにするツールである。これにより実際の環境に近いテスト環境を構築し、外部リソースに対するテストをより簡単に行える。ここではKotestでTestcontainersを活用する方法について説明する。

Testcontainers

Testcontainersは、独立して再利用可能なテスト環境を構築するためのツールである。コンテナベースのテストをサポートし、ローカルマシンで実行されるテスト環境と同じ環境をプログラムで構築できる。KotestはTestcontainersと一緒に使用でき、テストに必要な外部リソースを管理し、より堅牢で信頼できるテストを書くのに役立つ。

Testcontainersを使用する主な利点は次のとおりである。

  1. 一貫した環境: 各テストが実行されるたびに一貫した環境を提供し、テスト結果を予測できる。
  2. 独立性: 外部リソースをコンテナ化し、テストが互いに影響しないよう保証する。
  3. テスト環境構築の容易さ: コードでテスト環境をプログラム的に構築し管理できる。
  4. 多様なコンテナサポート: Docker、Kubernetesなど、さまざまな種類のコンテナをサポートし、多様なテストシナリオを構築できる。

Testcontainersプロジェクトは、テスト内部で使用するのに理想的な一般的なデータベース、Elasticsearch、Kafka、Selenium Webブラウザ、またはその他Dockerコンテナで実行できるあらゆるものの軽量な一時インスタンスを提供する。

Kotestは、データベースおよびKafka向けの特殊な拡張、サポートされるすべてのDockerイメージに対する汎用コンテナサポートなど、複数の拡張機能を提供する追加モジュールを通じてTestcontainersとの統合を提供する。

依存関係の追加

使用するには、Gradleビルドファイルに次の依存関係を追加する必要がある。

dependencies {
    testImplementation("io.kotest.extensions:kotest-extensions-testcontainers:${kotestVersion}")
}

参考: io.kotest.extensionsのGroup IDは、基本Kotest(io.kotest)とは異なる。

Mavenプロジェクトの場合は、次のように依存関係を追加する。

<dependency>
    <groupId>io.kotest.extensions</groupId>
    <artifactId>kotest-extensions-testcontainers</artifactId>
    <version>${kotest.version}</version>
    <scope>test</scope>
</dependency>

Databases

KotestでTestcontainersを使用する方法は簡単である。テストコード内でTestcontainersライブラリを使って必要なコンテナを起動し、テストを実行した後にコンテナを整理すればよい。

たとえば、データベース連携テストを行う場合、テスト開始時にデータベースコンテナを起動し、テスト終了時にコンテナを停止するのが一般的である。

このためにKotestでは、beforeTestafterTestを使用して、テスト実行前後に必要な作業を実行できる。

以下はKotestとTestcontainersを一緒に使用するサンプルコードである。

import io.kotest.core.spec.style.FreeSpec
import org.testcontainers.containers.PostgreSQLContainer
import org.testcontainers.junit.jupiter.Container
import org.testcontainers.junit.jupiter.Testcontainers

@Testcontainers
class PostgreSqlTest : FreeSpec() {

    companion object {
        @Container
        val postgresContainer: PostgreSQLContainer<Nothing> = PostgreSQLContainer<Nothing>()
            .withDatabaseName("test")
            .withUsername("test")
            .withPassword("test")
            .withExposedPorts(5432)
    }

    override fun beforeTest(testCase: TestCase) {
        postgresContainer.start()
        System.setProperty("DB_URL", postgresContainer.jdbcUrl)
        System.setProperty("DB_USERNAME", postgresContainer.username)
        System.setProperty("DB_PASSWORD", postgresContainer.password)
    }

    override fun afterTest(testCase: TestCase, result: TestResult) {
        postgresContainer.stop()
    }

    init {
        "Database test" {
            // データベーステストコード作成
        }
    }
}

上のコードでは、PostgreSQLコンテナを使用してデータベーステストを行う。@Testcontainersアノテーションを使用してTestcontainersを有効化し、@Containerアノテーションを使用してコンテナを定義する。そしてbeforeTestafterTestをオーバーライドし、テスト実行前後にコンテナを起動、停止する。


参照