Kotlinでtestcontainers-javaをつかう
概要
Testcontainersってなに?
プログラムからDockerコンテナを起動できるライブラリ 最近testcontainers-javaとJUnit5のjupiterへの親和性が高くなったらしいので試したメモです。
環境
どうする
pomに依存を足す
依存にはTestcontainersとJUnit5と、ドキュメントにはでてきていないような気がするけど、 Testontainersが作っているJUnit5用のExtensionが必要です 今回はPostgreSQLのコンテナを試してみるのでPostgreSQL用の依存も追加します。
<!-- pom抜粋 --> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>${junit.jupiter.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.testcontainers</groupId> <artifactId>testcontainers</artifactId> <version>${testcontainers.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.testcontainers</groupId> <artifactId>junit-jupiter</artifactId> <version>${testcontainers.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.testcontainers</groupId> <artifactId>postgresql</artifactId> <version>${testcontainers.version}</version> <scope>test</scope> </dependency>
テストクラスを作る
クラスに@Testcontainers
アノテーションをつけて、PostgreSQLContainer
というクラスのインスタンスを作ってあげるだけでOK。
クラス変数として作成するとテストクラスのインスタンス生成時にDBが起動して、テストが全て終わったら停止します。
インスタンス変数にすると各テストメソッドごとに起動と停止が実行されます。
インスタンス生成時にデータベース名やUsername/Passwordも一緒に設定できます。
@Suppress("NonAsciiCharacters", "TestFunctionName") @Testcontainers class SampleTestContainer { companion object { @Container private val container = PostgreSQLCotainer() .withDatabaseName("postgres") .withUsername("postgres") .withPassword("") } @Test fun コンテナが起動している() { assertTrue(container.isRunning) } }
と思ったら
SELF-TypeReferenceが使われてて、今のKotlinだとそのままインスタンス化はできない?らしいので、 継承したクラスを作ってお茶を濁すことに。。(この辺あまり詳しくないです
class PostgreSQLKotainer : PostgreSQLContainer<PostgreSQLKotainer>() // ... 抜粋 ... @Container private val container = PostgreSQLKotainer() // ...........
気をつけること
Dockerなのでどうしても起動に待ち時間が必要になります。
1回だけ実行するならそんなに気にならないけど、開発時に何回も実行するとなるとツライ。
テストを実行する前に起動して、テスト実行中はTRUNCATE
やDROP
を使いつつ、すべてのテストが終わったら停止するような使い方が良さそうに感じました。