Day 1: Cypressの世界へようこそ
今日学ぶこと
- E2Eテストとは何か、なぜ必要なのか
- テストピラミッドの概念(Unit, Integration, E2E)
- Cypressとは何か、その特徴と利点
- Cypress vs Selenium の比較
- Cypressのアーキテクチャ
- インストールと初期セットアップ
- Cypress Test Runnerの使い方
E2Eテストとは何か
Webアプリケーションを開発していると、「ボタンをクリックしたら正しい画面に遷移するか」「フォームに入力して送信したらデータが保存されるか」といった動作を確認する必要があります。これを手動で毎回確認するのは大変です。
E2E(End-to-End)テストとは、ユーザーが実際にアプリケーションを操作するのと同じように、ブラウザを自動操作してアプリケーション全体の動作を検証するテスト手法です。
flowchart LR
subgraph Manual["手動テスト"]
M1["ブラウザを開く"]
M2["フォームに入力"]
M3["ボタンをクリック"]
M4["結果を目視確認"]
end
subgraph E2E["E2Eテスト(自動)"]
E1["cy.visit()"]
E2["cy.type()"]
E3["cy.click()"]
E4["cy.should()で自動検証"]
end
M1 --> M2 --> M3 --> M4
E1 --> E2 --> E3 --> E4
style Manual fill:#f59e0b,color:#fff
style E2E fill:#22c55e,color:#fff
なぜE2Eテストが必要なのか
| 課題 | E2Eテストによる解決 |
|---|---|
| 手動テストは時間がかかる | 自動で数分で完了 |
| 人間はミスをする | 毎回同じ手順を正確に実行 |
| リグレッション(退行)の検出が困難 | 変更のたびに全体を自動チェック |
| 複数ブラウザでの確認が大変 | 複数ブラウザで自動実行可能 |
| 深夜のデプロイ後の確認 | CI/CDパイプラインで自動実行 |
テストピラミッド
ソフトウェアテストには、目的や範囲によって複数の種類があります。これを体系的に表したのがテストピラミッドです。
flowchart TB
subgraph Pyramid["テストピラミッド"]
E2E["E2Eテスト\n(少数・高コスト・高信頼)"]
INT["インテグレーションテスト\n(中程度)"]
UNIT["ユニットテスト\n(多数・低コスト・高速)"]
end
E2E --> INT --> UNIT
style E2E fill:#ef4444,color:#fff
style INT fill:#f59e0b,color:#fff
style UNIT fill:#22c55e,color:#fff
| テストの種類 | 対象 | 速度 | コスト | 例 |
|---|---|---|---|---|
| ユニットテスト | 関数・コンポーネント単体 | 速い | 低い | 計算関数の入出力テスト |
| インテグレーションテスト | 複数コンポーネントの連携 | 中程度 | 中程度 | APIとDBの連携テスト |
| E2Eテスト | アプリケーション全体 | 遅い | 高い | ユーザーログインフロー |
テストピラミッドの原則
- ユニットテストを最も多く書く:高速で安定しているため
- E2Eテストは重要なフローに絞る:実行が遅くメンテナンスコストが高いため
- バランスが重要:各層のテストが補完し合うことで品質を担保する
Cypressとは
Cypressは、モダンなWebアプリケーションのためのE2Eテストフレームワークです。2014年にBrian Mannによって開発が始まり、従来のSeleniumベースのテストツールが抱えていた課題を根本的に解決することを目指して設計されました。
Cypressの主な特徴
- ブラウザ内で直接実行:テストコードがアプリケーションと同じブラウザ内で動作する
- 自動待機(Auto-waiting):要素の表示やアニメーションの完了を自動で待つ
- タイムトラベルデバッグ:テストの各ステップをスナップショットで確認できる
- リアルタイムリロード:テストファイルを保存すると自動で再実行される
- スタブとスパイ:ネットワークリクエストを簡単にモック・インターセプトできる
flowchart TB
subgraph Features["Cypressの特徴"]
F1["自動待機\nAuto-waiting"]
F2["タイムトラベル\nデバッグ"]
F3["リアルタイム\nリロード"]
F4["ネットワーク\nスタブ"]
F5["スクリーンショット\n・動画記録"]
end
style Features fill:#3b82f6,color:#fff
Cypress vs Selenium
E2Eテストツールとして長い歴史を持つSeleniumとCypressを比較してみましょう。
flowchart TB
subgraph Selenium["Selenium のアーキテクチャ"]
S_TEST["テストコード"]
S_DRIVER["WebDriver"]
S_BROWSER["ブラウザ"]
S_APP["アプリケーション"]
end
subgraph Cypress["Cypress のアーキテクチャ"]
C_TEST["テストコード"]
C_BROWSER["ブラウザ(同一プロセス内)"]
C_APP["アプリケーション"]
end
S_TEST --> S_DRIVER --> S_BROWSER --> S_APP
C_TEST --> C_BROWSER
C_BROWSER --> C_APP
style Selenium fill:#f59e0b,color:#fff
style Cypress fill:#3b82f6,color:#fff
Seleniumはテストコードとブラウザの間にWebDriverという中間層を挟むのに対し、Cypressはブラウザ内で直接テストコードを実行します。この違いが、多くの利点をもたらします。
| 比較項目 | Selenium | Cypress |
|---|---|---|
| アーキテクチャ | WebDriver経由で外部からブラウザを操作 | ブラウザ内で直接実行 |
| セットアップ | WebDriverのインストールと管理が必要 | npm install のみ |
| 対応言語 | Java, Python, C#, Ruby, JavaScript等 | JavaScriptのみ |
| 対応ブラウザ | Chrome, Firefox, Safari, Edge, IE | Chrome, Firefox, Edge, Electron |
| 自動待機 | 手動でwaitを記述 | 組み込みの自動待機 |
| デバッグ | 困難(外部プロセス) | タイムトラベルデバッグ |
| ネットワーク制御 | 外部プロキシが必要 | 組み込みのインターセプト |
| 実行速度 | 比較的遅い | 高速 |
| 学習コスト | 高い | 低い |
Cypressが向いているケース
- モダンなJavaScriptフレームワーク(React, Vue, Angular等)のテスト
- フロントエンド中心のE2Eテスト
- 開発チームがJavaScriptに精通している場合
- 迅速なフィードバックループが必要な場合
Seleniumが向いているケース
- 多言語対応が必要な場合
- Safariやレガシーブラウザのテストが必須の場合
- 大規模なクロスブラウザテストが必要な場合
Cypressのアーキテクチャ
Cypressは従来のテストツールとは根本的に異なるアーキテクチャを持っています。
flowchart TB
subgraph Browser["ブラウザ(Electron / Chrome)"]
subgraph CypressRunner["Cypress Test Runner"]
SPEC["テストファイル\n(spec.cy.js)"]
CMD["Cypressコマンド\n(cy.get, cy.click等)"]
end
subgraph AppFrame["アプリケーション iframe"]
APP["テスト対象\nアプリケーション"]
DOM["DOM"]
end
CMD --> DOM
end
subgraph NodeServer["Node.js サーバー"]
PROXY["プロキシ"]
FILE["ファイルシステム"]
NET["ネットワーク制御"]
end
Browser <--> NodeServer
style Browser fill:#3b82f6,color:#fff
style NodeServer fill:#8b5cf6,color:#fff
style CypressRunner fill:#22c55e,color:#fff
style AppFrame fill:#f59e0b,color:#fff
アーキテクチャの要点
- テストコードはブラウザ内で実行される:アプリケーションと同じ実行環境にあるため、DOMに直接アクセスできる
- Node.jsサーバーがバックエンドを担当:ファイル操作やネットワーク制御はNode.jsプロセスが処理する
- プロキシによるネットワーク制御:全てのHTTPリクエストをプロキシ経由にすることで、リクエストのインターセプトやモックが可能
インストールとセットアップ
前提条件
- Node.js 18以上がインストールされていること
- npm または yarn が使えること
インストール手順
# プロジェクトディレクトリを作成
mkdir my-cypress-project
cd my-cypress-project
# package.json を初期化
npm init -y
# Cypressをインストール
npm install cypress --save-dev
インストールが完了すると、node_modules/.bin/cypress に実行ファイルが配置されます。
初回起動
# Cypress Test Runnerを起動
npx cypress open
初回起動時、Cypressは以下のディレクトリ構造を自動的に作成します。
my-cypress-project/
├── cypress/
│ ├── e2e/ # テストファイルを配置するディレクトリ
│ ├── fixtures/ # テストデータ(JSON等)
│ ├── support/ # カスタムコマンドやグローバル設定
│ │ ├── commands.js # カスタムコマンドの定義
│ │ └── e2e.js # E2Eテスト用のグローバル設定
│ └── downloads/ # ダウンロードファイルの保存先
├── cypress.config.js # Cypress設定ファイル
└── package.json
cypress.config.js の基本設定
Cypressの設定ファイルは cypress.config.js です。主要な設定項目を見ていきましょう。
const { defineConfig } = require('cypress')
module.exports = defineConfig({
e2e: {
// テスト対象アプリケーションのベースURL
baseUrl: 'http://localhost:3000',
// テストファイルのパターン
specPattern: 'cypress/e2e/**/*.cy.{js,jsx,ts,tsx}',
// ビューポートサイズ
viewportWidth: 1280,
viewportHeight: 720,
// テスト失敗時のスクリーンショット
screenshotOnRunFailure: true,
// テスト実行の動画記録
video: false,
// タイムアウト設定(ミリ秒)
defaultCommandTimeout: 4000,
pageLoadTimeout: 60000,
// リトライ設定
retries: {
runMode: 2, // cypress run 時のリトライ回数
openMode: 0, // cypress open 時のリトライ回数
},
setupNodeEvents(on, config) {
// Node.jsイベントリスナーの登録
},
},
})
主要な設定項目
| 設定項目 | デフォルト値 | 説明 |
|---|---|---|
baseUrl |
null | cy.visit('/') のベースURL |
viewportWidth |
1000 | ブラウザの幅 |
viewportHeight |
660 | ブラウザの高さ |
defaultCommandTimeout |
4000 | コマンドのタイムアウト(ms) |
pageLoadTimeout |
60000 | ページ読み込みのタイムアウト(ms) |
video |
false | テスト実行の動画記録 |
screenshotOnRunFailure |
true | 失敗時のスクリーンショット |
retries |
{ runMode: 0, openMode: 0 } |
テストのリトライ回数 |
Cypress Test Runnerの画面
npx cypress open でTest Runnerを起動すると、GUIが表示されます。
Test Runnerの主な構成要素
- テストタイプ選択画面:E2EテストまたはComponent Testingを選択
- ブラウザ選択:テストを実行するブラウザを選択(Chrome, Firefox, Edge, Electron)
- テストファイル一覧:実行可能なテストファイルが表示される
- テスト実行画面:左側にコマンドログ、右側にアプリケーションプレビュー
ヘッドレスモードでの実行
CI/CD環境ではGUIなしで実行します。
# ヘッドレスモードで全テスト実行
npx cypress run
# 特定のテストファイルのみ実行
npx cypress run --spec "cypress/e2e/login.cy.js"
# 特定のブラウザで実行
npx cypress run --browser chrome
まとめ
| 概念 | 説明 |
|---|---|
| E2Eテスト | ユーザー操作を自動化してアプリケーション全体を検証するテスト |
| テストピラミッド | Unit → Integration → E2E の3層構造。下層ほど多く書く |
| Cypress | ブラウザ内で直接実行されるモダンなE2Eテストフレームワーク |
| 自動待機 | 要素の表示やアニメーションの完了をCypressが自動で待つ機能 |
| タイムトラベル | テストの各ステップをスナップショットで確認できるデバッグ機能 |
| cypress.config.js | Cypressの設定ファイル。baseUrlやタイムアウト等を設定 |
重要ポイント
- E2Eテストは手動テストを自動化し、リグレッションを防ぐために不可欠
- Cypressはブラウザ内で直接実行されるため、高速で安定したテストが可能
- 自動待機機能により、テストコードにsleepやwaitを書く必要がない
練習問題
問題1: 基本
テストピラミッドの3つの層をそれぞれ説明し、各層でどのようなテストを書くべきか例を挙げてください。
問題2: 応用
CypressとSeleniumのアーキテクチャの違いを説明し、Cypressのアーキテクチャがもたらす利点を3つ挙げてください。
チャレンジ問題
新しいプロジェクトでCypressをセットアップし、cypress.config.js に以下の設定を追加してください:ベースURLを http://localhost:8080、ビューポートサイズを1920x1080、デフォルトコマンドタイムアウトを10秒に設定。
参考リンク
次回予告: Day 2では「はじめてのテストを書こう」について学びます。テストファイルの構造を理解し、実際にTodoアプリのE2Eテストを書いてみましょう。