10日で覚えるCypressDay 1: Cypressの世界へようこそ

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の主な特徴

  1. ブラウザ内で直接実行:テストコードがアプリケーションと同じブラウザ内で動作する
  2. 自動待機(Auto-waiting):要素の表示やアニメーションの完了を自動で待つ
  3. タイムトラベルデバッグ:テストの各ステップをスナップショットで確認できる
  4. リアルタイムリロード:テストファイルを保存すると自動で再実行される
  5. スタブとスパイ:ネットワークリクエストを簡単にモック・インターセプトできる
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

アーキテクチャの要点

  1. テストコードはブラウザ内で実行される:アプリケーションと同じ実行環境にあるため、DOMに直接アクセスできる
  2. Node.jsサーバーがバックエンドを担当:ファイル操作やネットワーク制御はNode.jsプロセスが処理する
  3. プロキシによるネットワーク制御:全ての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の主な構成要素

  1. テストタイプ選択画面:E2EテストまたはComponent Testingを選択
  2. ブラウザ選択:テストを実行するブラウザを選択(Chrome, Firefox, Edge, Electron)
  3. テストファイル一覧:実行可能なテストファイルが表示される
  4. テスト実行画面:左側にコマンドログ、右側にアプリケーションプレビュー

ヘッドレスモードでの実行

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やタイムアウト等を設定

重要ポイント

  1. E2Eテストは手動テストを自動化し、リグレッションを防ぐために不可欠
  2. Cypressはブラウザ内で直接実行されるため、高速で安定したテストが可能
  3. 自動待機機能により、テストコードにsleepやwaitを書く必要がない

練習問題

問題1: 基本

テストピラミッドの3つの層をそれぞれ説明し、各層でどのようなテストを書くべきか例を挙げてください。

問題2: 応用

CypressとSeleniumのアーキテクチャの違いを説明し、Cypressのアーキテクチャがもたらす利点を3つ挙げてください。

チャレンジ問題

新しいプロジェクトでCypressをセットアップし、cypress.config.js に以下の設定を追加してください:ベースURLを http://localhost:8080、ビューポートサイズを1920x1080、デフォルトコマンドタイムアウトを10秒に設定。


参考リンク


次回予告: Day 2では「はじめてのテストを書こう」について学びます。テストファイルの構造を理解し、実際にTodoアプリのE2Eテストを書いてみましょう。