【Go言語】Testcontainers で PostgreSQL を起動する3つの方法
はじめに
コンテナを利用したテストを快適に実行するために Testcontainers というライブラリがあります。
テスト実行前の環境構築が不要であったり、テスト実行のたびにコンテナをクリーンアップできたり、コンテナを並列起動することでテストデータの干渉などを考えなくてよくなります。
似たようなライブラリで ory/dockertest というライブラリがありますが、現在は Testcontainers がおすすめされています。
追記: 2024-07-20
Testcontainers を使いましょう。
この Testcontainers を利用して PostgreSQL との統合テストを実装しようと思ったのですが、コンテナを起動する方法がいくつか選択肢があったのでそれぞれ実装して比較してみました。
PostgreSQL コンテナ起動時に求めること
以下のことができればよいなという想定です。
- 任意のユーザーやパスワードの設定
- マイグレーションの実施
- golang-migrate/migrate などのファイル管理を想定
- ヘルスチェック
3つの起動方法
ドキュメントを眺めてみた感じ、3つの方法で PostgreSQL コンテナはセットアップできそうでした。( PostgreSQL に限らず他のコンテナも同じ方式でセットアップはできそうです。 )
- 汎用的なコンテナ起動
- PostgreSQL モジュールの起動
- Docker Compose による起動
1. 汎用的なコンテナ起動
1つ目はクイックスタートにも記載されている関数 testcontainers.GenericContainer()
を利用する方法です。
この関数を使えば任意のコンテナが起動できます。
docker-entrypoint-initdb.d
を指定してマイグレーションを実施させます。
ディレクトリを指定したかったのですが、うまく動かなかったのでファイルごとにコピーするようにしています。
2. PostgreSQL モジュールの起動
2つ目はモジュールごとに用意された関数 postgres.Run()
を利用する方法です。
実際は1つ目で紹介した関数をモジュールごとに使いやすくラップしたものになります。
各種設定値が専用のオプションとして設定できるので1つ目の方法よりパラメータの扱いが PostgreSQL に沿った形式で設定できます。
DSN 情報も専用のメソッドが用意されているので安全に接続情報を取得できます。
こちらも docker-entrypoint-initdb.d
を指定してマイグレーションを実施させますが、1つ目の方法同様にディレクトリの指定ができなかったのでファイルごとにコピーする手法をとっています。
3. Docker Compose による起動
3つ目は Docker Compose ファイルを利用する関数 compose.NewDockerComposeWith()
を利用する方法です。
compose.yaml
ファイルを利用してコンテナを起動します。
実行時に決定したい値は ${}
で記載しておきます。
マイグレーションについては compose.yaml
で docker-entrypoint-initdb.d
で記載したとおりディレクトリがマウントされ実行されます。
おわりに
個人的には compose.yaml
を利用したセットアップが好みです。
利用するイメージを compose.yaml
で管理できるので renovate と組み合わせればバージョン更新漏れなどが減らせそうです。
また、サービス指定ができるのでローカル環境構築用のファイルと併用も可能かと思います。
今回実装したコードは以下に置いておきます。
Discussion