は、利用者と同じ経路でシステム全体を動かす検証です。「本当に動くか」に最も近いという点で、他の層に代えがたい価値があります。同時に、遅く・壊れやすく・失敗の原因が読めないという三重の弱点を抱えています。
以前は「書くのが大変」という理由でも抑制が効いていました。いまはその抑制が外れています。書けるようになったからこそ、意識的に線を引く必要があります。
1. E2E にしかできないこと
まず、E2E を残す理由を明確にします。下の層でどれだけ検証しても確認できないものがあるからです。
- 部品がつながっていること — 個々は正しいのに配線が間違っている、という事故は下の層では捕まらない
- 設定と環境 — 環境変数、権限、ルーティング。コードは正しいが設定が違う類の問題
- 画面としての成立 — 要素が存在し、操作でき、遷移する。人が触る前提の確認
- 認証・セッションの通し — ログインしてから目的の操作にたどり着けるか
共通しているのは、「単体では正しいのに、組み上げると動かない」種類の問題であることです。逆に言うと、計算やロジックの正しさを E2E で確認するのは筋が悪い。それは下の層の仕事で、E2E でやると遅く不安定な検証に置き換えてしまうことになります。
「配線の確認」です。中身が正しいかではなく、つながっているかを見る。この定義に絞ると、必要な本数は自然に少なくなります。
2. 何を対象に選ぶか
対象の選定は、EP.1 で挙げた優先順位(損害の大きさ × 頻度)をそのまま使えます。加えて E2E 固有の観点として、その経路が通らないとサービスとして成立しないかを見ます。
| 経路の性質 | E2E にする | 理由 |
|---|---|---|
| 登録 → ログイン → 主要操作 | する | 通らなければサービスが成立しない |
| 決済・申込の完了まで | する | 損害が直接的で、配線の問題が起きやすい |
| 管理画面の一括操作 | 場合による | 利用者が限られる。頻度と損害で判断 |
| 入力値のバリデーション網羅 | しない | 下の層で速く網羅できる |
| 表示文言・レイアウト | しない | 変更頻度が高く、壊れやすさに見合わない |
「バリデーション網羅」を E2E でやってしまう例は非常に多いです。画面から入力できるからという理由で書けてしまうのですが、10 パターン検証したければ 10 回ブラウザを起動することになります。同じ検証は下の層なら一瞬で終わります。
3. 壊れにくく書く
E2E が壊れる原因の大半は、要素の指定方法と待ち方の2つです。ここを直すだけで安定性は大きく変わります。
// クラス名はデザイン変更で変わるawait page.click('.btn-primary.submit-lg');
// 固定待ち。遅い環境では足りず、速い環境では無駄await page.waitForTimeout(3000);
// 表示文言の変更で壊れるawait expect(page.locator('text=送信が完了しました')).toBeVisible();// テスト用の識別子で指定する(デザイン変更の影響を受けない)await page.getByTestId('submit-order').click();
// 条件が満たされるまで待つ(環境の速さに左右されない)await page.getByTestId('order-complete').waitFor({ state: 'visible' });
// 文言ではなく、状態を表す属性を見るawait expect(page.getByTestId('order-status')).toHaveAttribute('data-state', 'completed');テスト用の識別子を要素に付けることには「本番のコードにテストの都合を持ち込むのか」という反対意見もあります。ただ実務的には、識別子を付けないことによる保守コストのほうが明らかに大きいというのが率直なところです。デザイン変更のたびに E2E が全滅する状況と比べれば、属性が1つ増えるコストは小さい。
表示文言での要素指定は書きやすいが最も壊れやすい選択です。文言は仕様変更でも翻訳でも変わります。文言そのものを検証したい場合を除き、識別子か役割で指定してください。
4. 失敗したときに原因が分かるようにする
E2E の三重苦のうち、原因が読めないという点は、書き方ではなく証跡の残し方で大きく改善できます。落ちた瞬間の状態を残しておけば、再現を試みる前に当たりがつきます。
- 失敗時のスクリーンショット — 何が表示されていたかが一目で分かる
- 操作の記録(トレース) — どこまで進んで、どこで止まったか
- ブラウザのコンソールログ — 画面には出ないエラーを拾える
- 通信の記録 — API が失敗していたのか、画面側の問題かを切り分けられる
これらは主要な E2E フレームワークが標準で持っている機能です。有効にしていないだけというケースが多いので、まず設定を確認する価値があります。証跡がないと、 なのか本物の不具合なのかすら判断できません。
5. 増やさないための運用
線を引いても、放っておけば E2E は増えます。「念のため」で追加されるからです。抑制を仕組みにしておくと維持しやすくなります。
- 1追加するときに、下の層で代替できないか必ず問う — 大半は代替できる
- 2実行時間の上限を決めておく — 超えたら追加ではなく入れ替えを検討する
- 3失敗したら必ず誰かが見る、を守れる本数に保つ — 見きれない量は多すぎる証拠
- 4定期的に、落ちたことのないテストを見直す — 一度も守ったことがない可能性がある
4番目は見落とされがちです。一度も失敗したことのない E2E は、安定して価値を出しているのか、それとも何も検証していないのか、区別がつきません。 のように意図的に壊してみて、落ちることを確認する価値があります。
6. 線引きの結論
E2E は配線の確認に絞り、主要導線だけを対象にし、識別子と条件待ちで書き、証跡を残す。これが現時点で妥当な線だと考えています。「本当に動くか」を確認できる唯一の層なので、なくすのではなく、役割を狭めて維持可能にするという方向です。
なお、E2E の実行時間は の費用に直結します。実行時間と費用の関係については エンジニアリング・ダッシュボード EP.05「CI/CD コストの可視化」 が参考になります。連載としては EP.10 で改めて扱います。
E2E の役割は配線の確認。ロジックの検証は下の層に降ろす。壊れにくさは識別子での指定と条件待ちでほぼ決まる。失敗時の証跡がないと原因判別ができない。次回は、変更で壊していないことを確認する の設計を扱います。
この記事の感想を教えてください
あなたの 1 クリックで、本当にこの記事は更新されます。「もっと詳しく」「続編希望」が一定数集まった記事は、 ふくふくが 実際に内容を拡充したり続編記事を公開 します。 送信したリアクションはお使いのブラウザに記録され、再カウントされません。