Go E2E テスト
別プロセスのアプリには Go テスト内の状態を直接渡せません。exec.CommandContext の Cmd.Env を nil にすると、起動時の環境変数を継承します。プロセス起動前に fx.ShadowPG(t) を呼べば、子プロセスにフォークの DATABASE_URL と libpq の PG* 変数が渡ります。アプリのデータソース設定コードは変更しません。
func TestBrowserCheckout(t *testing.T) { fx.ShadowPG(t) cmd := exec.CommandContext(t.Context(), "./app-test-server") // Cmd.Env が nil なので Start 時の os.Environ() を継承する if err := cmd.Start(); err != nil { t.Fatal(err) } t.Cleanup(func() { if cmd.Process != nil { _ = cmd.Process.Kill() } _ = cmd.Wait() })
// アプリのヘルスチェックを待ってから UI や API を操作する waitForHealth(t, appURL) // browser.Navigate(appURL + "/checkout")}この例では os/exec と testing を import します。app-test-server、waitForHealth、appURL は既存アプリの起動方法と準備完了判定に置き換えてください。テストごとにアプリを起動するか、ワーカーごとのアプリとフォークを維持して逐次テストの間にフォークを復元します。復元前に DB トランザクションを終了してください。並列実行するアプリには、それぞれ別のフォークとプロセスを用意します。
ShadowPG はテスト終了までテストプロセスの環境を変更するため、t.Parallel() と併用できません。起動済みのプロセスを後から切り替えることもできません。起動コードが Cmd.Env を明示する場合は、ShadowPG の後で os.Environ() をコピーし、ポートなどの設定を追加してください。
安全な並列実行
Section titled “安全な並列実行”プロセス単位のワーカーを使います。go test -p 4 ./... ならパッケージごとに別のテストバイナリが起動します。1 パッケージを分割する場合は、重複しない -run 条件の go test -run ... -count=1 を複数プロセスで起動します。各ワーカーは ShadowPG で環境を設定した後に独自のアプリ子プロセスを起動し、別の HTTP ポートとブラウザーセッションを使います。アプリプロセスやフォークをワーカー間で共有しないでください。同じワーカーではフォークの reset・終了前にブラウザーのリクエスト、DB のバックグラウンドジョブ、トランザクションを完了させます。-parallel 1 を指定しても t.Parallel() と ShadowPG は併用できません。