E2E(End-to-End/エンドツーエンド)テストは、利用者が実際にたどる操作の連なりを端から端まで通しで動かし、画面・API・データベース・外部サービスがつながった状態で業務が完了するかを確かめるテストです。単体テストや結合テストが部品と部品の受け渡しを確かめるのに対し、E2Eテストは「ログインして商品を選び、決済まで到達できるか」を丸ごと再現します。この記事では、結合テストとの違い、Playwright・Cypress・Seleniumの選び分け、各ツールの公式ドキュメントが示すベストプラクティス、そしてE2Eを内製するか外注するかの判断基準までを、実務で下せる判断の形にして整理します。
まとめ|E2Eテスト導入で最初に決める3つのこと
E2Eテストで最初に決めるべきは、本数ではなく対象を絞る基準です。E2Eは実行が遅く、UI変更で壊れやすく、維持コストが恒常的に発生します。したがって「止まると売上か顧客対応に直結する主要動線」に限定し、それ以外は結合テストと単体テストへ落とすのが合理的でしょう。網羅率を目標に据えてE2Eを増やす運用は、実行時間の膨張と失敗調査の負債を生むため推奨しません。
次がセレクタと待機の方針。E2Eが壊れやすいと言われる原因の大半は、手法そのものではなくCSSクラスへの依存と固定秒数の待機という2つの実装習慣にあります。PlaywrightもCypressも公式ドキュメントで同じ方向の指針を示しており、この2点を最初に規約化するかどうかで維持コストは大きく変わります。
最後が誰が保守し続けるかです。E2Eテストは作って終わりではなく、機能追加のたびに追従が必要な資産。追従できる体制が社内に無いまま外注で本数だけ作ると、半年後には全件が赤いまま放置される状態に陥ります。以降では定義と違いを押さえたうえで、ツール選定・公式準拠のベストプラクティス・内製と外注の切り分けを順に見ていきます。
E2Eテストの定義と、E2Eテストでしか見つからない欠陥
E2Eテストの検証対象=つながった状態の業務フロー
E2Eテストは、システムを構成要素に分解せず、利用者と同じ入口から同じ出口まで操作して結果を確かめます。ECサイトなら「商品検索→カート投入→ログイン→配送先入力→決済→注文確定メール」までが1本のシナリオで、途中に自社APIも決済代行も在庫管理も含まれるわけです。検証の主体はコードではなく画面上の振る舞いであり、内部実装を知らない立場から結果だけを判定する点でブラックボックステストとホワイトボックステストの基本的な違いとは何かで扱うブラックボックス側に属します。
実施タイミングは、単体テストと結合テストが通ったあと、リリース判断の直前。プログラムを動かして確かめる動的テストの一種であり、コードを実行せずに欠陥を探す静的解析とは検出できる欠陥が重なりません。両者の守備範囲は静的解析と動的テストの違いとは|検出できるバグ・代表ツール・使い分けを比較で整理しています。
単体テスト・結合テストが構造的に見逃す欠陥の4類型
E2Eを入れる価値は、部品単位のテストが構造的に見逃す欠陥に絞って考えると判断しやすくなります。個々のモジュールがすべて仕様どおりでも、つないだ瞬間に破綻する典型が次の4つです。
- 設定・環境差の欠陥:ステージングでは通るがCORS設定やCookieのSameSite属性が本番構成と異なり、決済リダイレクト後にセッションが切れる
- 画面遷移とルーティングの欠陥:APIは200を返しているのに、遷移先のURLが誤っていて完了画面に到達しない
- 非同期処理の完了待ちの欠陥:注文APIの応答前に完了画面を描画してしまい、失敗時に成功表示が残る
- 外部サービス連携の欠陥:決済代行のWebhook受信が遅延し、注文ステータスが更新されないまま確定扱いになる
いずれもモックを使う結合テストでは再現しにくく、実際につないで通してみるまで表面化しません。逆に言えば、この4類型に該当しない不具合の検出はE2Eの得意分野ではないため、計算ロジックや条件分岐の網羅は単体テストへ寄せたほうが、同じ工数で多くの欠陥を早く見つけられます。サービス間の入出力が壊れていないかだけを速く検知したい場合は、契約テストによる消費者駆動契約の実装とCI組み込みを併用すると、E2Eの本数を増やさずに連携の破壊を捕まえられます。
単体テスト・結合テストとの違いと、テスト配分の決め方
3階層の検証範囲・実行時間・壊れやすさの比較
E2Eテストと結合テスト(統合テスト)の違いは「どこまでを本物でつなぐか」に集約されます。結合テストがモジュール間やAPI間の受け渡しを確かめる段階であるのに対し、E2Eは外部連携まで含めた全体を本物でつなぎます。なお「システムテスト」は開発工程の名称、E2Eテストはテスト手法の名称という違いがあり、対象範囲としてはほぼ重なると考えて差し支えありません。3階層の性質は次のとおりです。
| テストの層 | 検証範囲 | 実行時間の目安 | 変更で壊れる頻度 | 欠陥箇所の特定 |
|---|---|---|---|---|
| 単体テスト | 関数・クラス単位 | ミリ秒〜秒 | 低 | 容易 |
| 結合テスト | モジュール間・API間 | 秒 | 中 | やや容易 |
| E2Eテスト | 画面からDB・外部連携まで | 十数秒〜分 | 高 | 困難 |
表の右2列がE2Eの本質的なコストです。1本の失敗から原因箇所を突き止めるまでの時間が長く、しかもUI変更のたびに壊れます。
テストピラミッドとテスティングトロフィーの使い分け基準
配分の考え方には、単体テストを最も多くしE2Eを頂点の少数に留めるテストピラミッドと、結合テストを最も厚くするテスティングトロフィーの2つがあります。フロントエンドの比重が高く、コンポーネント同士の組み合わせで欠陥が出やすいプロダクトではトロフィー型が現実に合いやすく、バックエンドのロジックが厚い基幹系ではピラミッド型が機能するでしょう。両者の違いと使い分けはTesting Trophy(テスティングトロフィー)とは?テストピラミッドとの違いと理想のテスト配分を解説で詳しく扱っています。
どちらを採るにせよ、E2Eが最上段の少数派である点は共通。E2Eの本数が結合テストを上回っている状態は、配分設計が崩れているサインと考えて差し支えありません。テスト量そのものの妥当性を数値で確認したい場合は、バグ密度・テスト密度の目安|IPA基準値と計算式・ゾーン分析の基準値が判断材料になります。
E2Eテストツールの選び分け(Playwright・Cypress・Selenium)
主要3ツールの版・ライセンス・実行モデル
2026年7月27日時点で、npmレジストリが返す各ツールの最新版とライセンスは次のとおりです。実行モデルの違いが、そのまま「できること」の差になります。
| ツール | 版(2026-07時点) | ライセンス | 実行モデル | 対応言語 |
|---|---|---|---|---|
| Playwright | 1.62.0 | Apache-2.0 | ブラウザ外から制御 | TS・JS・Python・Java・.NET |
| Cypress | 15.19.0 | MIT | ブラウザ内で実行 | TS・JS |
| Selenium WebDriver | 4.46.0 | Apache-2.0 | WebDriver経由 | Java・Python・JS・C#・Ruby |
Playwrightはブラウザの外側からプロトコルで制御するため、複数タブ・複数オリジン・別ドメインへのリダイレクトを1本のシナリオで扱えます。バージョン1.62はChromium 151.0.7922.34、Firefox 153.0、WebKit 26.5を同梱し、npx playwright install の1コマンドで3エンジンが揃うため、Safari系を含むクロスブラウザ検証を早期に始められる点が実務上の強みです。
Cypressはテストコードをブラウザ内で動かす設計で、開発中のデバッグ体験に優れます。公式のTrade-offsは「各テストは単一のスーパードメインに束縛される」としたうえで、オリジンをまたぐ遷移は cy.origin コマンドで有効にできると明記しています。ただし cy.origin のコールバック内では cy.intercept と cy.session がエラーになり、コールバックはクロージャではないため外側の変数を参照できず args オプションで値を渡す必要があります。越境そのものは可能でも、書き方に制約が残る点は選定時に押さえておきたいところです。Cypressでの具体的な書き方はE2EテストをCypressで自動化する方法とその実践例で扱っています。
Seleniumは対応言語の広さとWebDriverという標準仕様が資産で、JavaやC#で書かれた既存のテスト基盤がある組織では引き続き有力。新規に始めるならPlaywright、既存のCypress資産があるならCypress継続、言語やレガシー環境の制約があるならSelenium、という順で検討するのが実務的です。
専用ツールを使わない標準テストランナーでのE2E
E2E=ブラウザ自動化ツール、と決めてかかる必要はありません。検証したい対象がAPIとデータベースまでで、画面操作が本質でないなら、その言語の標準テストランナーからHTTPリクエストを投げるだけでE2Eは成立します。Goなら追加の依存を入れずに go test でシナリオを書けます。
func TestOrderFlow(t *testing.T) {
res, err := http.Post(baseURL+"/api/orders", "application/json", body)
if err != nil {
t.Fatal(err)
}
defer res.Body.Close()
if res.StatusCode != http.StatusCreated {
t.Fatalf("want 201, got %d", res.StatusCode)
}
}
この選択肢の利点は、ブラウザを起動しないぶん実行が桁違いに速く、フレークの主因であるレンダリング待ちが消えること。開発者が普段書いているテストと同じ書き方になるため、専任のQAだけでなく実装担当者が自分でE2Eを書ける状態にしやすい効果もあります。裏を返せば、画面のバリデーションやフロントエンド側の状態遷移は一切検証できません。「決済の状態遷移が正しく進むか」を守りたいのか「入力フォームが利用者に正しく見えるか」を守りたいのかを分け、前者は標準テストランナー、後者はブラウザ自動化ツール、と使い分けるのが無駄がないでしょう。画面の見た目の変化まで押さえたい場合は、VRT(Visual Regression Testing)とは?必要性・メリットと主要ツール・Playwright実装をわかりやすく解説で扱う視覚回帰テストが別軸の手段になります。
クラウド実行基盤・商用ツールへ費用を払う判断軸
OSSツールは導入費用がかからない代わりに、実行環境の構築と保守を自前で持ちます。BrowserStackやSauce Labsのようなクラウド実行基盤、AutifyやmablのようなAI補助付きの商用テストツールに支払う価値が出るのは、次の条件に当てはまるときです。
- 検証すべきブラウザとOSの組み合わせが多く、自前でマシンを維持するより従量課金のほうが安い
- 実行の並列度を上げたいが、CI基盤の増強に手が回らない
- テストを書くのが非エンジニアで、コードレスの記録・再生が必要
- 失敗時の動画・トレースの保管と共有を、仕組みとして担保したい
これらのサービスの課金は、同時実行数(並列枠)か実行時間を単位とする体系が中心です。価格は改定されるため、比較検討時は各社の公式料金ページで最新の条件を確認してください。逆に、対象ブラウザがChromiumのみで、実行本数が数十件に収まり、書き手が全員エンジニアであれば、OSSとGitHub Actionsの組み合わせで十分に運用できます。テストケースの管理面まで含めて整えたい場合はテスト管理ツールの併用も選択肢になり、TestRailとは?テスト管理ツールの機能・料金・使い方を解説が比較の起点になります。
公式ドキュメントに学ぶエンドツーエンドテストのベストプラクティス
セレクタ指定の2方式(役割ベースとテスト専用属性)
Playwright公式のベストプラクティスは「XPathやCSSセレクタより利用者に見える属性を優先する」と明示し、page.locator('button.buttonIcon.episode-actions-later') のようなクラス依存の指定を壊れやすい例として挙げています。推奨されるのは page.getByRole('button', { name: 'submit' }) のように、役割と表示名で要素を特定する書き方です。
// 実装の都合ではなく、利用者に見える役割と文言で指定する
await page.getByRole('button', { name: '注文を確定する' }).click();
await expect(page.getByText('ご注文を受け付けました')).toBeVisible();
Cypress公式は別の道筋で同じ問題に対処します。id・class・タグ名での指定を避け、data-cy のような data-* 属性を要素に付けて「CSSやJSの変更から切り離せ」と指示しています。どちらの方針も狙いは共通で、見た目のリファクタリングがテストの失敗に化けない状態を作ることです。
固定待機の排除と、自動待機・アサーションによる同期
Cypress公式はアンチパターンとして「cy.wait(Number) による任意の秒数待機」を名指しし、代わりにルートのエイリアスかアサーションで明示的な条件が満たされるまで待てと示しています。cy.request()・cy.visit()・cy.get() には待機機構が組み込まれているため、後ろに秒数待機を足す必要はありません。
// NG: 3秒待てば終わっているだろう、という前提が環境差で崩れる
// cy.wait(3000);
// OK: 注文APIの応答を待ってから次に進む
cy.intercept('POST', '/api/orders').as('createOrder');
cy.get('[data-cy=submit-order]').click();
cy.wait('@createOrder');
Playwrightではweb-first assertionsが同じ役割を担い、await expect(page.getByText('welcome')).toBeVisible() は条件が満たされるまで自動的に待機します。固定秒数の待機は、速いマシンでは無駄に遅く、遅いCIでは足りないという二重の損。フレークの調査では、まずこの固定待機を探すのが定石です。
テスト間の独立性と外部依存の排除
Cypress公式は「複数のテストを結合させる」ことをアンチパターンとし、どのテストも単独で実行して合格する状態を求めています。あわせて、後片付けを after や afterEach で行うのも避けるよう指示。テストが途中で中断されると後片付けが走らないため、クリーンアップはテストの前、つまり beforeEach に置くのが公式の推奨です。前のテストが作ったデータに次のテストが依存する設計は、並列実行を導入した瞬間に破綻します。
外部依存についても両者の指針は一致します。Playwright公式は「自分が制御するものだけをテストする」とし、外部サイトやサードパーティのサーバーへのリンクを検証対象にせず、Network APIで応答をモックするよう示しています。Cypress公式も、自分が制御しないサイトの訪問を避け、サードパーティAPIは cy.request() で扱うこと、CAPTCHAやA/Bテストの影響を受けるソーシャルログインの画面操作を避けることを挙げました。決済代行のテスト環境が落ちただけで自社のCIが赤くなる構成は、テストの信頼性を自ら下げていることになります。
フレークテストと実行時間の膨張を抑えるCI運用
フレークの主因と切り分けの順序
同じコードで成功と失敗を繰り返すフレークテストは、放置するとチームがテスト結果を信用しなくなり、赤いまま無視される状態に至ります。原因の切り分けは、頻度の高い順に次の順序で見るのが早道。第一に固定待機と非同期処理の同期漏れ、第二にテスト間のデータ共有、第三にアニメーションやレンダリング完了前の操作、第四にCIマシンの性能差やネットワーク遅延です。前の3つはテストコード側で解消できる問題で、実際の原因の大半がここに含まれます。
リトライで隠すのは最後の手段ですが、切り分け中の暫定運用としては有効です。Playwright 1.62では設定ファイル側のオプションとして retryStrategy が追加されました。既定値は 'immediate'(ワーカーが空き次第すぐ再実行)で、retryStrategy: 'isolated' を明示すると、公式の説明どおりリトライを全テスト終了後に単一ワーカーで1件ずつ回します。並列実行中の他テストからの干渉を排除した状態で再実行できるため、「並列だと落ちるが単独なら通る」タイプのフレークを切り分ける材料になるわけです。ただしリトライ回数を増やして緑にする運用は欠陥の検出力を落とすだけなので、原因の記録と紐づけて期限を切って使うべきでしょう。
分割実行によるCI実行時間の短縮
E2Eは1本あたり十数秒から分単位かかるため、本数が増えると直列実行では現実的な時間に収まりません。Playwrightはシャーディングで実行を分割でき、CI側で複数ジョブに並べれば実行時間をほぼ分割数に反比例して短縮できます。
npx playwright test --shard=1/4
npx playwright test --shard=2/4
組み込み先の設計では、全件をプルリクエストごとに回さない判断が効きます。主要動線の数本だけをプルリクエスト時に実行し、全件はマージ後か夜間のスケジュール実行に回す構成なら、開発の待ち時間を増やさずに回帰検出を維持できるでしょう。ワークフローの具体的な書き方はGitHub Actionsとは?できること・使い方とCI/CD自動化の活用例をわかりやすく解説が参考になります。失敗時のトレースと動画を成果物として保存する設定は、原因調査の時間を最も短縮する投資。最初のワークフローから入れておくことを勧めます。
E2Eテストを内製するか外注するかの判断基準
内製が成立する条件と外注が合理的な条件
E2Eテストの外注で失敗する典型は、テストの作成だけを切り出して発注し、保守の担い手を決めないまま納品を受けるパターンです。E2Eは仕様変更のたびに追従が必要な資産なので、作成コストより維持コストのほうが総額では大きくなります。内製が成立するのは、テストコードを読み書きできる開発者が社内に常時いて、機能追加のプルリクエストと同じ流れでテストも直せる体制があるとき。目安として、主要動線10〜20本程度の規模であれば、機能改修のたびに数本を直す作業は実装担当者の通常業務に吸収できます。
外注が合理的なのは、対象ブラウザや端末の組み合わせが多く検証工数が一時的に跳ね上がる場合、リリース前の受け入れ確認だけを回したい場合、そして社内にテスト設計の経験者がいない立ち上げ期です。ただし立ち上げ期に外注する場合でも、テストコードの所有権と実行環境を自社に置き、社内メンバーが読める形で残すことを前提にしないと、次の改修で作り直しになります。
外注時に取り決める成果物と引き継ぎ範囲
発注前に合意しておくべき項目は、テスト本数ではなく引き継ぎ可能性に関わるものです。具体的には、使用ツールとバージョン、テストコードのリポジトリ所有者(著作権と二次利用の範囲を含む)、セレクタの規約(data-* 属性を実装側に入れるかどうか)、テストデータの準備方法、CIでの実行手順書、そして検収後の瑕疵対応期間とフレーク発生時の対応範囲です。
特にセレクタ規約は、実装側のHTMLに手を入れる必要があるため、テスト側だけでは決められません。ここを曖昧にしたまま進めると、外注先がCSSクラスを掴むしかなくなり、納品直後のデザイン修正で全件が壊れます。発注時点で「テスト専用属性の付与は自社の実装タスク」と決めておくことが、外注の成否を分ける最も実務的な一手です。
よくある質問
E2Eテストと結合テスト(統合テスト)は何が違いますか?
つなぐ範囲が違います。結合テストはモジュール間やAPI間の受け渡しが正しいかを、外部依存をモックに置き換えて確かめます。E2Eテストは画面からデータベース、外部サービスまでを本物のままつなぎ、利用者と同じ操作で業務が完了するかを確かめる手法です。結合テストが「部品どうしが正しく話しているか」、E2Eが「その全体が使えるか」を見る、と切り分けると迷いません。
E2Eテストはどのツールから始めるのがよいですか?
新規で制約が無ければPlaywright(2026年7月時点の最新版は1.62.0、Apache-2.0)が第一候補です。Chromium・Firefox・WebKitを同梱するため npx playwright install だけでクロスブラウザ検証を始められ、複数オリジンをまたぐシナリオも扱えます。既にCypress(15.19.0、MIT)で書かれた資産があるなら移行の必要はありません。JavaやC#の既存テスト基盤に載せるならSelenium WebDriver(4.46.0)が現実的でしょう。
E2Eテストはすべて自動化すべきですか?
すべきではありません。自動化が向くのは、繰り返し実行する価値があり、期待結果が明確で、頻繁に仕様が変わらない主要動線です。逆に、リリースごとにデザインが変わる画面、実行頻度が数か月に一度の業務、判断に人の目が要る表示崩れの確認は、手動のほうが総コストで安く済みます。自動化の対象を絞ることは手抜きではなく、維持コストを設計に織り込む判断です。
E2Eテストが不安定で失敗し続ける場合はどうすればよいですか?
本文で示した切り分け順序(固定待機の排除→テスト間のデータ共有の解消→セレクタをテスト専用属性か役割ベースへ変更)をそのまま適用してください。ここまでで大半のフレークは解消します。リトライは原因調査の時間を稼ぐ暫定策として使い、恒久対策にはしないことです。
小規模なプロダクトでもE2Eテストは必要ですか?
必要ですが、本数は1〜3本で足ります。小規模でも「サインアップして主要機能を1回使う」動線が壊れれば事業が止まる点は変わりません。この最小構成であれば実行時間もCI費用も無視できる範囲に収まり、維持の負担もほとんど生じないでしょう。小規模で避けるべきなのはE2E自体ではなく、網羅を目的に本数を増やすことです。