ウェブエンジニア問題集

E2Eテストの基本 — ユーザー操作をそのまま再現する

E2Eテスト(End-to-End Test)は、システム全体を 実際のブラウザを通してテストする 手法です。フロントエンドからバックエンド、データベースまで — 「端から端まで」をユーザーの操作シナリオに基づいて検証します。

この章では、E2Eテストの位置づけとツール選定、何をE2Eでテストすべきかの判断基準を整理します。

学習者学習者

ブラウザを丸ごと動かすE2E、すごく便利そう。でも全部E2Eで書いちゃダメなの?


E2Eテストの特徴

PCを使う女性のイラスト

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 です。

ツール開発元特徴
PlaywrightMicrosoftマルチブラウザ対応、高速、活発な開発
CypressCypress社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モードによるデバッグまでを実践します。