E2Eテストの基本 — ユーザー操作をそのまま再現する
E2Eテスト(End-to-End Test)は、システム全体を 実際のブラウザを通してテストする 手法です。フロントエンドからバックエンド、データベースまで — 「端から端まで」をユーザーの操作シナリオに基づいて検証します。
この章では、E2Eテストの位置づけとツール選定、何をE2Eでテストすべきかの判断基準を整理します。
学習者ブラウザを丸ごと動かすE2E、すごく便利そう。でも全部E2Eで書いちゃダメなの?
E2Eテストの特徴

E2Eテストが他のテストと決定的に違うのは、実際のブラウザ環境を使う 点です。
| 特徴 | 結合テスト(Testing Library) | E2Eテスト(Playwright) |
|---|---|---|
| 実行環境 | jsdom(仮想DOM) | 実際のブラウザ(Chromium等) |
| CSS描画 | されない | される |
| Cookie/セッション | 模擬的 | 実際に動く |
| 画面遷移 | ルーティングをモック | 実際にナビゲーション |
| ネットワーク | MSW等でモック | 実際のAPIサーバーと通信 |
jsdomではCSSの描画が行われないため、「CSSで display: none にした要素がクリックできてしまう」という問題が起きえます。E2Eテストは実際のブラウザ上でテストするため、ユーザーが体験する挙動と一致します。
E2Eテストで確認すべきこと
E2Eテストは実行コストが高いため、すべてのケースを書くのは現実的ではありません。クリティカルパス — つまり「これが壊れたらビジネスに直接影響する操作フロー」に絞ります。
E2Eテストに向いているもの
- ユーザー登録・ログイン・ログアウト — 認証フローは複数のシステムが絡み、Cookie/セッションの挙動が重要
- 決済・購入フロー — ミスが許されない操作。フォーム → 確認 → 完了の画面遷移を通しで確認
- 主要な業務フロー — そのアプリのコア機能。ECなら「商品検索 → カート → 決済」
- 画面遷移を伴う複数ステップの操作 — ウィザード形式のフォームなど
E2Eテストに向かないもの
- バリデーションの個別ケース — 「メールアドレスの形式チェック」は単体テストで
- UIコンポーネントの表示パターン — ローディング、空状態、エラー表示は結合テストで
- APIのレスポンス形式 — APIの結合テストで
ツールの選定 — なぜPlaywrightか
E2Eテストのツールは複数ありますが、現在最も推奨されるのが Playwright です。
| ツール | 開発元 | 特徴 |
|---|---|---|
| Playwright | Microsoft | マルチブラウザ対応、高速、活発な開発 |
| Cypress | Cypress社 | DXが良い、ダッシュボードが充実 |
| Selenium | コミュニティ | 歴史が長い、多言語対応 |
Playwrightが推奨される理由
1. マルチブラウザ対応
Chromium、Firefox、WebKitの3つのブラウザエンジンをサポートしています。1つのテストコードで複数ブラウザの動作確認ができます。
2. 高速で安定
Playwrightはブラウザとの通信にWebSocketを使い、テストの実行が高速です。また、自動待機(auto-waiting)機能により、要素がクリック可能になるまで自動で待つため、不安定なテスト(Flaky Test)が起きにくい設計です。
3. 活発なコミュニティと開発
Microsoftが開発しており、頻繁にアップデートが行われています。近年のnpmダウンロード数の伸びも大きく、エコシステムが急拡大しています。
4. 強力なツール群
コード生成(Codegen)、UIモード、トレースビューア、スクリーンショットなど、テストの作成・デバッグを支援するツールが充実しています。
E2Eテストの基本構造
Playwrightのテストは以下のような構造です。
import { test, expect } from '@playwright/test';
test('トップページが表示される', async ({ page }) => {
// ページに遷移
await page.goto('/');
// タイトルを確認
await expect(page).toHaveTitle(/ウェブエンジニア問題集/);
// 要素が表示されていることを確認
await expect(page.getByRole('heading', { name: '教科書' })).toBeVisible();
});page オブジェクトがブラウザのタブに対応し、ナビゲーション、要素の取得、クリック、入力などの操作を行います。
ユーザー操作のシナリオ
test('ユーザーがログインしてダッシュボードにアクセスできる', async ({ page }) => {
// 1. ログインページに遷移
await page.goto('/login');
// 2. フォームに入力
await page.getByLabel('メールアドレス').fill('alice@example.com');
await page.getByLabel('パスワード').fill('password123');
// 3. ログインボタンをクリック
await page.getByRole('button', { name: 'ログイン' }).click();
// 4. ダッシュボードに遷移したことを確認
await expect(page).toHaveURL('/dashboard');
await expect(page.getByText('ようこそ、Aliceさん')).toBeVisible();
});E2Eテストの実行コスト
E2Eテストのデメリットとして、実行時間とメンテナンスコストの問題があります。
実行時間
ブラウザの起動、ページ遷移、ネットワーク通信が発生するため、単体テストと比べて 桁違いに遅い です。
| テスト種別 | 1テストあたりの実行時間(目安) |
|---|---|
| 単体テスト | 数ミリ秒 |
| 結合テスト | 数百ミリ秒〜数秒 |
| E2Eテスト | 数秒〜数十秒 |
100件の単体テストは数秒で終わりますが、100件のE2Eテストは数分〜十数分かかることもあります。
メンテナンスコスト
UIの変更(ボタンのテキスト変更、レイアウト変更など)によってテストが壊れるため、UIの改修のたびにテストの修正が必要になることがあります。
まとめ
- E2Eテストは 実際のブラウザ を使い、システム全体をユーザー操作で検証する
- Cookie、画面遷移、CSS描画など、jsdomではカバーできない部分を確認できる
- クリティカルパス に絞って書く。すべてのケースをE2Eで書くのはコストに見合わない
- ツールは Playwright が現在の第一選択肢。マルチブラウザ対応、高速、ツール群が充実
- 実行コストが高いため、テスト数は 厳選して管理 する
次の章では、Playwrightの導入からテストの書き方、UIモードによるデバッグまでを実践します。