cypress、nightwatch、puppeteer、testcafe、webdriverio は、すべて Web アプリケーションのテストやブラウザ自動化を目的としたツールですが、アーキテクチャとアプローチが異なります。cypress は開発者体験を重視した独自のランナーを持ち、リアルタイムでのデバッグが強みです。nightwatch と webdriverio は WebDriver プロトコルに基づき、クロスブラウザテストやモバイルテストに強く、特に webdriverio は拡張性が高いです。puppeteer は Chrome DevTools Protocol (CDP) を直接操作し、Chrome 環境での高速な自動化やスクレイピングに適しています。testcafe は WebDriver を必要とせず、独自の URL 書き換え技術で動作するため、セットアップが簡単で安定した実行を提供します。
Web アプリケーションの品質を保証するため、cypress、nightwatch、puppeteer、testcafe、webdriverio はそれぞれ異なる技術アプローチを採用しています。単に「テストができる」という点では同じですが、ブラウザをどう制御し、どうコードを実行するかという根本的な部分で大きな違いがあります。ここでは、実務的な観点からこれら 5 つのツールを比較します。
ツールがブラウザをどう動かすかは、テストの安定性や速度に直結します。
cypress はアプリケーションと同じランタイム(ブラウザ内)でテストコードを実行します。
// cypress: ブラウザ内で実行
cy.visit('/login');
cy.get('#username').type('user');
cy.get('#password').type('pass');
cy.get('button').click();
nightwatch は Selenium WebDriver プロトコルを使用します。
// nightwatch: WebDriver プロトコル
browser.url('http://localhost/login');
browser.setValue('#username', 'user');
browser.setValue('#password', 'pass');
browser.click('button');
puppeteer は Chrome DevTools Protocol (CDP) を直接叩きます。
// puppeteer: CDP 直接制御
const page = await browser.newPage();
await page.goto('http://localhost/login');
await page.type('#username', 'user');
await page.type('#password', 'pass');
await page.click('button');
testcafe は WebDriver を使わず、独自の技術で動作します。
// testcafe: 独自の注入方式
await t.navigateTo('/login');
await t.typeText('#username', 'user');
await t.typeText('#password', 'pass');
await t.click('button');
webdriverio は WebDriver プロトコルをベースにしつつ、CDP も併用できます。
// webdriverio: WebDriver + CDP
await browser.url('http://localhost/login');
await $('#username').setValue('user');
await $('#password').setValue('pass');
await $('button').click();
テストの安定性は、要素が描画されるのをどう待つかにかかっています。
cypress は自動的にリトライと待機を行います。
wait を明示的に書く必要がほとんどありません。// cypress: 自動リトライ
cy.get('.loaded-element').should('be.visible');
// 要素が現れるまで自動的に待機しリトライ
nightwatch はコマンドチェーン内で待機を管理します。
waitForElementVisible などの明示的な待機コマンドを使用します。// nightwatch: 明示的待機
browser.waitForElementVisible('.loaded-element', 5000);
browser.click('.loaded-element');
puppeteer は Promise ベースで、待機を明示的に記述します。
waitForSelector などを使って、特定の条件が満たされるまで待機します。// puppeteer: Promise 待機
await page.waitForSelector('.loaded-element');
await page.click('.loaded-element');
testcafe も自動待機機制を持ちます。
cypress に近い開発者体験を提供しつつ、アーキテクチャは異なります。// testcafe: 自動待機
await t.click('.loaded-element');
// 要素が操作可能になるまで自動的に待機
webdriverio は設定により自動待機を有効にできます。
waitForTimeout などの設定でグローバルな待機動作を定義可能です。// webdriverio: 設定または明示的待機
await $('.loaded-element').waitForDisplayed();
await $('.loaded-element').click();
テストが失敗したとき、原因を特定するまでの時間が開発効率を左右します。
cypress はタイムトラベルデバッグを提供します。
// cypress: コマンドログで状態確認
cy.get('button').debug();
// 実行を一時停止し、DevTools で状態を調査可能
nightwatch はコンソールログとスクリーンショットに依存します。
// nightwatch: スクリーンショット保存
browser.saveScreenshot('./logs/error.png');
console.log('Error occurred at login step');
puppeteer は DevTools プロトコルを活用したデバッグが可能です。
slowMo オプションで動作を遅くしたり、DevTools ウィンドウを表示したりできます。// puppeteer: 低速モードでデバッグ
const browser = await puppeteer.launch({ headless: false, slowMo: 100 });
// ブラウザが実際に操作されている様子を目視確認
testcafe はテストランナー上にエラー情報を表示します。
// testcafe: ビデオ録画設定
// testcafe "chrome" tests/ --video ./videos
// 失敗時に該当部分のビデオを確認可能
webdriverio は豊富なレポートオプションを持ちます。
wdio-spec-reporter などで詳細なログ出力が可能です。// webdriverio: ログ取得
const logs = await browser.getLogs('browser');
console.log(logs);
// コンソールエラーをテスト出力に含める
どのブラウザやデバイスでテストする必要があるかも選定基準になります。
cypress は主要デスクトップブラウザをサポートします。
// cypress: ブラウザ指定
// cypress run --browser chrome
// cypress run --browser firefox
nightwatch は Selenium グリッドを通じて広範なブラウザをカバーします。
// nightwatch: 環境設定
// nightwatch.conf.js で desiredCapabilities を設定
// browserName: 'safari', platform: 'MAC'
puppeteer は基本的に Chrome/Chromium です。
// puppeteer: モバイルエミュレーション
await page.emulate(iPhone);
// デバイス仕様を模倣して表示確認
testcafe はインストール済みのブラウザを自動的に検出します。
// testcafe: ブラウザ指定
testcafe 'chrome,firefox,safari' tests/
// コマンドラインで複数ブラウザを同時に指定可能
webdriverio は WebDriver 対応ブラウザすべてを扱えます。
// webdriverio: モバイル設定
// wdio.conf.js
// capabilities: [{ browserName: 'Chrome', platformName: 'Android' }]
| 特徴 | cypress | nightwatch | puppeteer | testcafe | webdriverio |
|---|---|---|---|---|---|
| 制御方式 | 独自プロキシ | WebDriver | CDP | URL 書き換え | WebDriver + CDP |
| 待機機制 | 自動リトライ | 明示的コマンド | 明示的 Promise | 自動待機 | 設定または明示的 |
| 主要ブラウザ | Chrome, FF, Edge | 全 WebDriver 対応 | Chrome (主) | 全インストール済み | 全 WebDriver 対応 |
| モバイルテスト | ❌ (エミュのみ) | ✅ (Appium) | ❌ (エミュのみ) | ✅ (リモート) | ✅ (Appium) |
| セットアップ | 簡単 | 中 (ドライバー要) | 簡単 (Chrome 限定) | 非常に簡単 | 中 (設定柔軟) |
| デバッグ | タイムトラベル | ログ/スクショ | DevTools 連携 | ビデオ/スクショ | レポート/ログ |
これら 5 つのツールに絶対的な正解はありません。プロジェクトの要件とチームの状況に合わせて選ぶ必要があります。
cypress は、モダンな Web アプリケーションの開発中で、開発者がテストを書きながらデバッグしたい場合に最適です。特にフロントエンド中心のプロジェクトで力を発揮します。
nightwatch は、Selenium エコシステムへの依存や、モバイルテストを含む幅広いカバレッジが必要な場合に適しています。確実性を求めるエンタープライズ環境でよく選ばれます。
puppeteer は、テストというよりはブラウザ自動化、スクレイピング、または Chrome 固有の機能検証を目的とする場合に選択すべきです。E2E テストフレームワークとして使うこともできますが、用途は限定的です。
testcafe は、環境構築の手間を極限まで減らしたいチームや、WebDriver の不安定さを避けたい場合に有効です。セットアップの速さと安定性のバランスが良いです。
webdriverio は、大規模で複雑なテストインフラを構築する場合に最も適しています。拡張性が高く、様々なプロトコルやサービスと統合できるため、長期的なメンテナンス性を重視するプロジェクトに向いています。
最終的には、チームがどのツールで最も生産的に働けるか、そしてプロジェクトの技術スタックとどのツールが最も自然にフィットするかで判断しましょう。
Chrome または Chromium 環境に特化した自動化、スクレイピング、または PDF 生成などを主目的とする場合に puppeteer を選択します。E2E テストよりもブラウザ制御そのものに焦点を当てるプロジェクトに向いています。
フロントエンド開発中に迅速なフィードバックループを求め、モダンなブラウザ(Chrome、Firefox、Edge)のみを対象とする場合に cypress を選択します。開発者ツールとの統合や、時間旅行デバッグ機能を重視するチームに最適です。
高度なカスタマイズ性、多様なプロトコル(WebDriver + CDP)のサポート、そして大規模なエコシステム統合を必要とする場合に webdriverio を選択します。マイクロサービスや複雑なインフラストラクチャを持つプロジェクトに推奨されます。
WebDriver のインストールや設定なしですぐにテストを始めたい場合、または複雑なブラウザ設定を避けたい場合に testcafe を選択します。セットアップの手間を減らし、安定した実行を優先するチームに適しています。
Selenium WebDriver ベースの確立されたエコシステムを必要とし、モバイルテスト(Appium 統合)やレガシーブラウザのサポートを維持する必要がある場合に nightwatch を選択します。
Puppeteer is a JavaScript library which provides a high-level API to control Chrome or Firefox over the DevTools Protocol or WebDriver BiDi. Puppeteer runs in the headless (no visible UI) by default
npm i puppeteer # Downloads compatible Chrome during installation.
npm i puppeteer-core # Alternatively, install as a library, without downloading Chrome.
Install chrome-devtools-mcp,
a Puppeteer-based MCP server for browser automation and debugging.
import puppeteer from 'puppeteer';
// Or import puppeteer from 'puppeteer-core';
// Launch the browser and open a new blank page.
const browser = await puppeteer.launch();
const page = await browser.newPage();
// Navigate the page to a URL.
await page.goto('https://developer.chrome.com/');
// Set screen size.
await page.setViewport({width: 1080, height: 1024});
// Open the search menu using the keyboard.
await page.keyboard.press('/');
// Type into search box using accessible input name.
await page.locator('::-p-aria(Search)').fill('automate beyond recorder');
// Wait and click on first result.
await page.locator('.devsite-result-item-link').click();
// Locate the full title with a unique string.
const textSelector = await page
.locator('::-p-text(Customize and automate)')
.waitHandle();
const fullTitle = await textSelector?.evaluate(el => el.textContent);
// Print the full title.
console.log('The title of this blog post is "%s".', fullTitle);
await browser.close();