CypressとSelenium WebDriverの比較：E2Eテストツールの改善点と選び方のポイント

# はじめに

E2Eテスト（End-to-Endテスト）とは、システム全体を通してユーザーの視点で動作確認を行うテストのことを言います。
E2Eテストは、導入や学習コストの高さなどの理由により、プロジェクトに導入されない場合が多いかと思います。
今回は、従来からあるE2EテストツールであるSelenium WebDriverと、比較的新しいツールのCypressを以下の観点で比較してみました。

* 導入の簡単さ
* テストコードの実装しやすさ
* 対応プログラミング言語の数
* 対応ブラウザの数
* 学習コスト
* 複数タブの対応

この記事ではWindows 11にインストールしたcypress 13.17.0とselenium-webdriver 4.27.0を使っています。

# 導入の簡単さ

## Selenium WebDriverの最短の導入方法（Windows11の場合）

1. Node.jsのインストール
    1. [サポートされているNode.jsのバージョン](https://www.npmjs.com/package/selenium-webdriver#node-support-policy)がインストールされていない場合は、以下の手順でインストール
    1. [Node.jsの公式サイト](https://nodejs.org/ja)からインストーラをダウンロード
    1. ダウンロードしたインストーラを実行してインストール
1. Selenium WebDriverのインストール
    1. ターミナルを開き、テストを作成したいディレクトリ内で`npm install selenium-webdriver`を実行
1. テストコードを記述するファイルの作成
    1. Selenium WebDriverをインストールしたディレクトリ内にテストコードを記述するファイルを作成（ファイル名の例：test.spec.js）
1. テストコードの記述
    1. [Selenium WebDriverの公式ドキュメント](https://www.selenium.dev/ja/documentation/)を参考にテストコードを記述
1. テストの実行
    1. `node {テストコードを記述したファイルの名前}`を実行（例：`node test.spec.js`）

## Cypressの最短の導入方法（Windows11の場合）

1. Node.jsのインストール
    1. [サポートされているNode.jsのバージョン](https://docs.cypress.io/app/get-started/install-cypress#Nodejs)がインストールされていない場合は、以下の手順でインストール
    1. [Node.jsの公式サイト](https://nodejs.org/ja)からインストーラをダウンロード
    1. ダウンロードしたインストーラを実行してインストール
1. Cypressのインストール
    1. ターミナルを開き、テストを作成したいディレクトリ内で`npm install cypress`を実行
1. Cypressの設定ファイルやテストコードを記述するファイル等の作成
    1. Cypressをインストールしたディレクトリで`npx cypress open`を実行し、開いたウインドウで以下の操作を行う
        1. 「E2E Testing」をクリック
        1. 「Continue」をクリック
        1. 表示されたブラウザのどれかを選択し、「Start E2E Testing in {選択したブラウザの名前}」をクリック
        1. 「Create new spec」をクリック
        1. ファイル名を変更したい場合は変更する
        1. 「Create spec」をクリック
        1. 「Okay, run the spec」をクリック
    1. `npx cypress open`を実行したターミナルでctrl+cを押下し、開いたウインドウを閉じる
1. テストコードの記述
    1. cypress/e2e/内の拡張子が.cy.jsのファイル（ファイル名を変更しなかった場合はcypress/e2e/spec.cy.js）内に[Cypressの公式ドキュメント](https://docs.cypress.io/app/get-started/why-cypress)を参考にテストコードを記述
1. テストの実行
    1. Cypressをインストールしたディレクトリで`npx cypress run`を実行することにより、headlessモードでテストを実行することが可能

## 両ツールの導入の簡単さの比較

導入の簡単さについては、Selenium WebDriverとCypressの間でそこまで差があるようには感じませんでした。

# テストコードの実装しやすさ

## ブラウザ操作

### Webサイトへのアクセス

```js
// Selenium WebDriver
await driver.get('https://example.com/')

// Cypress
cy.visit('https://example.com/')
```

### テキスト入力欄への入力

```js
// Selenium WebDriver
await driver.findElement(By.id('id')).sendKeys('入力するテキスト')

// Cypress
cy.get('#id').type('入力するテキスト')
```

### ボタンのクリック

```js
// Selenium WebDriver
await driver.findElement(By.id('id')).click()

// Cypress
cy.get('#id').click()
```

### セレクトボックスのオプションの選択（テキストで指定する場合）


```js
// Selenium WebDriver
const selectElement = await driver.findElement(By.id('id'))
const select = new Select(selectElement)
await select.selectByVisibleText('選択したいoption要素内のテキスト')

// Cypress
cy.get('#id').select('選択したいoption要素内のテキスト')
```

### チェックボックスをチェック状態にする

```js
// Selenium WebDriver
const checkbox = await driver.findElement(By.id('id'))
const isChecked = await checkbox.isSelected()
if (!isChecked) {
    await checkbox.click()
}

// Cypress
cy.get('#id').check()
```

## アサーション

Selenium WebDriver自体にはアサーション機能が組み込まれていないため、Jest、MochaなどのテストフレームワークやChaiなどのアサーションライブラリを組み合わせてアサーションを行う必要があります。
Cypressにはアサーション機能が組み込まれているため、アサーションを行うために他のテストフレームワークやライブラリを追加する必要がありません。

### Cypressを使用したアサーションの例

```js
// 要素内のテキストが指定の文字列と一致するかの確認
cy.get('h1').should('have.text', 'ページの見出しのテキスト')

// ページのタイトルが指定の文字列を含むかの確認
cy.title().should('include', 'ページのタイトル')

// 要素が表示されているかの確認
cy.get('#id').should('be.visible')

// 要素の中身が空であるかの確認
cy.get('#id').should('be.empty')
```

## 両ツールのテストコードの比較

ブラウザ操作のコードについては、Cypessの方が全体的に簡潔な記述になっています。
また、Cypressにはアサーション機能が組み込まれているため、別のテストフレームワークやライブラリのインストールが必要なSelenium WebDriverより、テストコードの実装が楽になった印象があります。

# 対応プログラミング言語の数

## Selenium WebDriverの対応プログラミング言語（2025/01/20現在）

* Java
* Python
* C#
* Ruby
* JavaScript
* Kotlin

（詳細は [Selenium WebDriverの公式サイト](https://www.selenium.dev/ja/documentation/) を参照）

公式に対応している上記の他に、PHP、Perl、Go、Swiftといった言語がコミュニティで広く利用されています。
独自のライブラリやラッパーにより、実用レベルで利用可能なプログラミング言語の数も10以上あります。

## Cypressの対応プログラミング言語（2025/01/20現在）

* JavaScript
* TypeScript

（詳細は [Cypressの公式サイト](https://docs.cypress.io/app/faq#Do-you-support-X-language-or-X-framework) を参照）

## 両ツールの対応言語の比較

Cypressが対応しているプログラミング言語はJavaScriptとTypeScriptだけです。
Selenium WebDriverは、対応しているプログラミング言語の数がCypressより多く、非公式で対応している言語も含めると20以上あります。
実装コードとテストコードを同じプログラミング言語で記述できる場合が多いことはSelenium WebDriverのメリットといえます。

# 対応ブラウザの数

## Selenium WebDriverの対応ブラウザ（2025/01/20現在）

Selenium WebDriverは以下のブラウザをサポートしています

* Chrome
* Edge
* Firefox
* Internet Explorer（Microsoft EdgeのInternet Explorerモードを使用）
* Safari

（詳細は [Selenium WebDriverの公式サイト](https://www.selenium.dev/ja/documentation/webdriver/browsers/) を参照）

また、Selenium WebDriverで使用するブラウザを変更するためには、テストコードを修正したり、コマンドライン引数で切り替えられるようにコードを実装したりする必要があります。

## Cypressの対応ブラウザ（2025/01/20現在）

Cypressは以下のブラウザをサポートしています

* Chrome
    * Chrome Beta
    * Chrome Canary
    * Chrome for Testing
* Chromium
* Edge
    * Edge Beta
    * Edge Canary
    * Edge Dev
* Electron
* Firefox
    * Firefox Developer Edition
    * Firefox Nightly
* WebKit
    * WebKitのサポートは実験段階であるため、問題が発生する可能性がある

（詳細は [Cypressの公式サイト](https://docs.cypress.io/app/references/launching-browsers) を参照）

Openモードでテストを実行する場合は、画面上でブラウザを切り替えることが可能です。
コマンドラインの場合は、「--browser」の後にブラウザ名を指定するだけで使用するブラウザを切り替えることができます。

```bash
# Chromeを使用してheadlessモードでテストを行う場合
npx cypress run --browser chrome
# Firefoxを使用してheadlessモードでテストを行う場合
npx cypress run --browser firefox
```

## 両ツールの複数ブラウザ対応についての比較

対応ブラウザの数についてはそこまで差があるとは感じませんでした。
使用するブラウザの切り替えについては、Cypressはコードの修正なしで切り替えが可能なため、便利になった印象があります。

# 学習コスト

学習コストについては、両ツールの公式ドキュメントのわかりやすさについて比較をしてみました。

## Selenium WebDriver

代表的なブラウザ操作、要素や要素の情報の取得方法、要素に対してのキーボードやマウスによる操作の方法などは以下のページ等で解説されています。

* [ブラウザー ナビゲーション](https://www.selenium.dev/ja/documentation/webdriver/interactions/navigation/)
* [ウィンドウとタブの操作](https://www.selenium.dev/ja/documentation/webdriver/interactions/windows/)
* [要素を探す](https://www.selenium.dev/ja/documentation/webdriver/elements/locators/)
* [Web要素に関する情報](https://www.selenium.dev/ja/documentation/webdriver/elements/information/)
* [Keyboard actions](https://www.selenium.dev/ja/documentation/webdriver/actions_api/keyboard/)
* [Mouse actions](https://www.selenium.dev/ja/documentation/webdriver/actions_api/mouse/)
* [選択要素の操作](https://www.selenium.dev/ja/documentation/webdriver/support_features/select_lists/)

## Cypress

公式ドキュメントの[Cypress API](https://docs.cypress.io/api/table-of-contents)のページ内に、ブラウザ操作を行うための各メソッドについて解説されたページへのリンクがあります。
以下は代表的なブラウザ操作やアサーションの方法について解説されたページへのリンクです。

* [visit（URLを指定してWebページを訪問）](https://docs.cypress.io/api/commands/visit)
* [get（セレクタ等を指定して要素を取得）](https://docs.cypress.io/api/commands/get)
* [contains（要素のテキストに含まれる文字列を指定して要素を取得）](https://docs.cypress.io/api/commands/contains)
* [type（DOM要素に文字列を入力）](https://docs.cypress.io/api/commands/type)
* [click（DOM要素をクリック）](https://docs.cypress.io/api/commands/click)
* [check（チェックボックスまたはラジオボタンをチェック）](https://docs.cypress.io/api/commands/check)
* [select（select要素内のoption要素を選択）](https://docs.cypress.io/api/commands/select)
* [Assertions（アサーション）](https://docs.cypress.io/app/references/assertions)

## 両ツールの公式ドキュメントの比較

Selenium WebDriverの公式ドキュメントでは、コードの例が不完全なため、「View full example on GitHub」というリンクの先のページを見ないとコードの例が分からない機能があります。
また、Cypressの公式ドキュメントの方が、機能がページごとにまとまって記載されており、分かりやすい印象があります。

# 複数タブの対応

## Selenium WebDriver

Selenium WebDriverでは、複数のタブを開いたり、現在開いているタブの数を取得したり、タブを切り替えたりといったテストを行うことが可能です。

（詳細は [Selenium WebDriverの公式サイト](https://www.selenium.dev/ja/documentation/webdriver/interactions/windows/) を参照）

## Cypress

Cypress単独では複数のタブを開くことはできないため、新しいタブを開いたり閉じたりする挙動のテストを行うことができません。
動作確認は行っていませんが、Puppeteerプラグインを利用することで、Cypressでも複数タブを使った操作が可能だという情報があります。

（詳細は [Cypressの公式サイト](https://docs.cypress.io/app/guides/migration/selenium-to-cypress#Multiple-tabs) を参照）

# まとめ

|  | Selenium WebDriver | Cypress | 備考 |
| ---- | ---- | ---- | ---- |
| 導入の簡単さ | 〇 | 〇 |  |
| テストコードの実装しやすさ | △ | 〇 |  |
| 対応プログラミング言語の数 | 6 ※1<br>（20以上 ※2） | 2 | ※1 公式対応の数<br>※2 ライブラリやラッパーにより非公式に対応している言語の数 |
| 対応ブラウザの数 | 5 | 5 ※3 | ※3 実験的サポートのWebKitを除く |
| ブラウザの切り替えの容易さ | △ | 〇 |  |
| 学習コスト（公式ドキュメントのわかりやすさ） | △ | 〇 |  |
| 複数タブの対応 | 〇 | △ ※4 | ※4 Puppeteerプラグインを使用することで可能という情報あり |

Selenium WebDriverには、対応しているプログラミング言語の数が多さ、実装コードとテストコードが同じプログラミング言語で記述できる場合が多いこと、プラグインなしで複数タブに対応していること等の利点があります。
テストコードをJavaScriptまたはTypeScriptで記述する場合かつ複数タブの操作が必須でない場合は、テストコードの実装しやすさ、ブラウザの切り替えの容易さ、公式ドキュメントのわかりやすさ等で利点のあるCypressもプロジェクトに導入するE2Eテストツールの選択肢となり得ると思います。