コンテンツにスキップ

Go E2E テスト

別プロセスのアプリには Go テスト内の状態を直接渡せません。exec.CommandContext の Cmd.Env を nil にすると、起動時の環境変数を継承します。プロセス起動前に fx.ShadowPG(t) を呼べば、子プロセスにフォークの DATABASE_URL と libpq の PG* 変数が渡ります。アプリのデータソース設定コードは変更しません。

e2e_test.go
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() をコピーし、ポートなどの設定を追加してください。

プロセス単位のワーカーを使います。go test -p 4 ./... ならパッケージごとに別のテストバイナリが起動します。1 パッケージを分割する場合は、重複しない -run 条件の go test -run ... -count=1 を複数プロセスで起動します。各ワーカーは ShadowPG で環境を設定した後に独自のアプリ子プロセスを起動し、別の HTTP ポートとブラウザーセッションを使います。アプリプロセスやフォークをワーカー間で共有しないでください。同じワーカーではフォークの reset・終了前にブラウザーのリクエスト、DB のバックグラウンドジョブ、トランザクションを完了させます。-parallel 1 を指定しても t.Parallel() と ShadowPG は併用できません。