Skip to content

Latest commit

 

History

History
76 lines (61 loc) · 3.1 KB

File metadata and controls

76 lines (61 loc) · 3.1 KB

CI/CD: 瞬時に立ち上がるテスト用DB

English version: ci-testing.md

考え方: スキーマとシードデータを最初から埋め込んだ実行ファイルを一度だけ ビルドし、あとは各テストジョブがそれを実行するだけにする——DBコンテナも マイグレーション手順も、サービスがhealthyになるのを待つ必要もない。

1. シード済みのスナップショットを一度だけビルドする

最新リリースから 自分のプラットフォーム用のバイナリを取得する(Go不要)、または Go 1.26以降があればgo install github.com/amisonnet8/execdb/cmd/execdb@latest でもよい。取得したら:

execdb <<'SQL'
CREATE TABLE users(id INTEGER PRIMARY KEY, name TEXT NOT NULL, email TEXT UNIQUE);
CREATE TABLE posts(id INTEGER PRIMARY KEY, user_id INTEGER REFERENCES users(id), title TEXT);
INSERT INTO users(name, email) VALUES ('Alice', 'alice@example.com'), ('Bob', 'bob@example.com');
INSERT INTO posts(user_id, title) VALUES (1, 'Hello World'), (1, 'Second post'), (2, 'Bob''s post');
.snapshot testdb
.exit
SQL

これで単独の実行ファイルtestdbができる——テスト用フィクスチャの ディレクトリへコミットするか、後続のジョブがダウンロードするCIの 成果物ステップとしてビルドする。(習慣としてソースリポジトリへExecDBの バイナリをコミットしないこと——これはテスト用フィクスチャという別の ケースであり、リリースバイナリ自体をコミットしない理由は .claude/rules/distribution.mdを 参照。)

2. テストジョブで使う

サーバーモードで実行し、アプリケーションのDATABASE_URLをそこへ向ける ——独立したコンテナも、ヘルスチェック待ちのステップも不要:

chmod +x testdb
./testdb -n -p 127.0.0.1:5432 -q &
SERVER_PID=$!

# テストスイート、例えば:
DATABASE_URL="postgres://any@127.0.0.1:5432/any" go test ./...

kill "$SERVER_PID"

データはメモリ上にあり、実行のたびに同じスナップショットから始まるため、 各ジョブはセットアップ時間ゼロで同一のまっさらなデータベースを得られる ——「Postgresコンテナを起動して待つ」というステップ自体が丸ごと消える。 ドライバごとの接続例はアプリケーションから接続するを 参照。

例: GitHub Actions

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - name: Start test database
        run: |
          chmod +x fixtures/testdb
          ./fixtures/testdb -n -p 127.0.0.1:5432 -q &
      - name: Run tests
        env:
          DATABASE_URL: postgres://any@127.0.0.1:5432/any
        run: go test ./...

services:ブロックもイメージのpullもポート待ちループも無い——データ ベースはジョブの中のただの1ステップになる。