E2Eテストで死なないための「賢い手抜き」と泥臭い生存戦略

E2Eテストで死なないための「賢い手抜き」と泥臭い生存戦略

E2Eテストを導入して「品質が爆上がりした」と喜んでいる連中を見ると、つい同情してしまう。その先にあるのは、UI変更のたびにテストが真っ赤に染まり、深夜に修正コードを叩く「メンテナンス地獄」という名の墓場だ。

以前、たった一行のCSS変更でテストが50個同時に沈黙した時の絶望は忘れられない。修正に丸一日を費やしたあの時、俺は悟った。「テストを書くこと」と「テストを維持すること」は全く別のスキルだと。

これは、自動化の罠にハマりかけた俺が、どうやって効率と精神の安定を取り戻したかの記録だ。


1. セレクタで消耗するのは「負け」と心得る

`div > div > span:nth-child(2)`。こんなセレクタを書いて悦に入っているなら、今すぐキーボードを置いてほしい。UIの構造が変われば即死する。

Playwrightを使うなら、「ユーザーがどう認識するか」をコードに落とし込むのが絶対の正解だ。

# 構造依存(死ぬコード)
page.locator(".btn-primary").click()

# ユーザー視点(生き残るコード)
page.get_by_role("button", name="ログイン").click()

`getByRole`を使えば、ボタンが`div`になろうが、クラス名が`css-xyz`に変わろうがテストは通る。これが「壊れにくいテスト」の第一歩だ。


2. 認証の「スキップ」は必須の生存戦略

ログイン画面のテストを毎回UI経由で実行するなんて、貴重なCPUと時間をドブに捨てているのと同じだ。認証基盤が少しでも揺らげば、全テストが連鎖的に死ぬ。

`storageState`を使って認証済みクッキーを使い回すのは基本だが、ここでハマるのが「セッション切れ」だ。

// playwright.config.ts
export default defineConfig({
  use: { storageState: 'auth.json' },
});

現場の泥臭い現実:
`auth.json`が期限切れになると、テストは「ログイン済み」のつもりで走るのに、実際はログイン画面にリダイレクトされてテストが落ちる「偽陰性」が発生する。俺はこれを防ぐために、CIパイプラインの先頭で「認証トークンが有効か」をチェックする小さなスクリプトを走らせ、期限切れなら再ログインしてファイルを更新する運用を組んでいる。


3. CI/CDを「沼」にしない並列化とレポート戦略

GitHub Actionsの無料枠を浪費して「今月はもうテストが回せません」なんて笑えない。テストが15分もかかれば、誰も結果を見なくなる。

シャーディングによる爆速化

`shard`を使ってテストを分割し、実行時間を物理的に削れ。

npx playwright test --shard=1/4

レポートの集約と「失敗のみ再実行」

分割実行するとレポートがバラバラになるが、`merge-reports`を使えば一元管理できる。さらに、「前回失敗したテストだけ再実行する」オプションは神だ。

# 失敗したテストだけをピンポイントで叩く
npx playwright test --last-failed

これで、CIの行列待ちと「テストが終わらないからマージできない」というストレスから解放される。


4. 「Network Idle」という甘い罠

`page.waitForLoadState('networkidle')`は、SPAの非同期通信が多い現場ではほぼ使い物にならない。APIレスポンス待ちでタイムアウトして、深夜に頭を抱えることになる。

実践的な解決策:
「通信が終わるまで」ではなく「データが描画されるまで」を待つのが鉄則だ。

# 特定のAPIレスポンスを待ってからUIを叩く
async with page.expect_response("**/api/v1/user-data") as response_info:
    await page.get_by_text("プロフィール編集").click()

# その後、要素が表示されるのを待つ
await expect(page.get_by_test_id("user-name")).to_be_visible()

「テストが不安定なら、それはコードのせいではなく、待機戦略が甘いだけ」だ。


5. E2Eは「捨て時」を見極めるゲーム

全部をテストしようとするな。それは開発者のエゴだ。俺たちは「クリティカルなパス」だけを守ればいい。

我がチームの運用ポリシー:
1. 決済・ログイン・データ保存:E2Eの聖域。絶対に壊してはいけない。
2. それ以外:ユニットテストか統合テストへ逃がす。
3. メンテナンスの分担:週次の交代制で「テストの健康診断」を実施。落ちたテストを放置する奴は、その週のコードレビュー権限を剥奪するくらいの厳しさで臨んでいる。

E2Eは完璧を目指すな。壊れやすい場所を避け、壊れにくい書き方で、最小限だけ守る。これが、プロジェクトを安定させ、俺たちが定時に帰るための唯一の道だ。

自動化は、君を楽にするためにある。君を苦しめるためのものではないことを、忘れないでほしい。