しおしお

IntelliJ IDEAのことなんかを書いてます

Testcontainersを使ったテストの高速化

Testcontainersを使ったテストは、コンテナの起動が毎回行われるのでどうしてもslow testになってしまいます。 そこで、一度あげたコンテナを使い回すことで2回目以降のテスト実行を高速化してみようと思います。

コンテナを使い回す設定を追加

コンテナを使い回す設定は、テストコードとTestcontainersの設定ファイルの両方に対して行う必要があります。 片方だけに設定を行っても有効にならないので注意です。

テストコード

テストコードで、コンテナを起動する際にreuse(org.testcontainers.containers.GenericContainer#withReuse)trueを設定してあげます。

    private val elasticsearchContainer: ElasticsearchContainer
    init {
        val time = measureNanoTime {
            elasticsearchContainer = ElasticsearchContainer("docker.elastic.co/elasticsearch/elasticsearch:7.11.1")
                .withCreateContainerCmdModifier {
                    it.withEntrypoint("/bin/bash", "-c", "./bin/elasticsearch-plugin install analysis-kuromoji && docker-entrypoint.sh")
                }
                .withLabel("filter-label", "plugin-install-test")
                .withReuse(true)
                .apply {
                    start()
                }
        }
        println("time >>>>> ${TimeUnit.NANOSECONDS.toMillis(time)}")
    }

Testcontainersの設定

上記のテストコードの設定に加えて$HOMEディレクトリ直下にある.testcontainers.propertiesに以下の設定を加えてあげます。 ファイルがない場合には、新規で作成して設定を追加する感じになります。

testcontainers.reuse.enable=true

実行結果

1回目と2回目の時間を比較してみると、コンテナ起動が省略でき、20秒ほど早くなっていることが確認できますね。

1回目

08:57:57.666 [Test worker] INFO 🐳 [docker.elastic.co/elasticsearch/elasticsearch:7.11.1] - Container docker.elastic.co/elasticsearch/elasticsearch:7.11.1 started in PT19.649672S
time >>>>> 21072

2回目

08:58:54.287 [Test worker] INFO 🐳 [docker.elastic.co/elasticsearch/elasticsearch:7.11.1] - Container docker.elastic.co/elasticsearch/elasticsearch:7.11.1 started in PT0.049485S
time >>>>> 1676

起動しっぱなしのコンテナの終了方法

Testcontainersで上げたコンテナンにはラベルが設定されているので、そのラベルでフィルターすることで簡単に終了できます。

コマンド的には、こんな感じになります。

docker ps --filter label=org.testcontainers -q | xargs docker stop

注意点

コンテナを使い回すことになるので、テスト開始時にクリーンな状態ではない可能性があります。 テストコードでは必ず前回のテストの状態を削除するなどして、きれいな状態にする必要があります。