puppeteer vs cypress vs testcafe vs nightwatch
フロントエンドE2Eテストツールの比較
puppeteercypresstestcafenightwatch類似パッケージ:
フロントエンドE2Eテストツールの比較

cypressnightwatchpuppeteertestcafeはいずれもJavaScript/TypeScriptエコシステムで広く使われるE2E(End-to-End)テストおよびブラウザ自動化ツールです。これらのパッケージは、Webアプリケーションのユーザーインターフェースを実際のブラウザ環境でテストし、回帰バグの検出や品質保証を支援します。cypresstestcafeはテストフレームワークとして統合された体験を提供し、nightwatchはWebDriverプロトコルを活用した伝統的なアプローチを採用しています。一方、puppeteerはChromiumをプログラムから制御するための低レベルライブラリであり、テスト以外の自動化タスクにも利用されます。

npmのダウンロードトレンド
3 年
GitHub Starsランキング
統計詳細
パッケージ
ダウンロード数
Stars
サイズ
Issues
公開日時
ライセンス
puppeteer7,512,50993,56863 kB2861日前Apache-2.0
cypress6,730,17949,5724.45 MB1,25711日前MIT
testcafe206,3369,9036.32 MB191ヶ月前MIT
nightwatch128,80511,9501.94 MB33624日前MIT

E2Eテストツール徹底比較: Cypress vs Nightwatch vs Puppeteer vs TestCafe

フロントエンド開発において、信頼性の高いE2E(End-to-End)テストは欠かせません。cypressnightwatchpuppeteertestcafeはいずれも人気のある選択肢ですが、アーキテクチャや使い勝手、対応範囲に大きな違いがあります。この記事では、実際の開発現場で直面する課題を軸に、各ツールの技術的特徴をコード例とともに詳しく見ていきます。

🧪 テスト記述スタイル:宣言的 vs 命令的

cypress は独自の非同期処理モデルを採用し、テストコードを同期的に記述できます。内部でPromiseチェーンを隠蔽しており、初心者にも書きやすいのが特徴です。

// cypress
it('ログインしてダッシュボードを表示', () => {
  cy.visit('/login');
  cy.get('#email').type('user@example.com');
  cy.get('#password').type('secret');
  cy.get('form').submit();
  cy.url().should('include', '/dashboard');
});

nightwatch はWebDriverプロトコルに基づき、命令的なスタイルで操作を記述します。非同期処理にはPromiseまたはコールバックを使用します。

// nightwatch
module.exports = {
  'ログインしてダッシュボードを表示': function (browser) {
    browser
      .url('/login')
      .setValue('#email', 'user@example.com')
      .setValue('#password', 'secret')
      .submitForm('form')
      .assert.urlContains('/dashboard')
      .end();
  }
};

puppeteer はChrome DevTools Protocol(CDP)を直接操作し、完全にプログラム可能な制御を提供します。Promiseベースで、細かいブラウザ操作が可能です。

// puppeteer
const puppeteer = require('puppeteer');

test('ログインしてダッシュボードを表示', async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('http://localhost:3000/login');
  await page.type('#email', 'user@example.com');
  await page.type('#password', 'secret');
  await page.click('form button[type="submit"]');
  expect(page.url()).toContain('/dashboard');
  await browser.close();
});

testcafe は独自の非同期ラッパーを使い、テストコードを同期的に記述できます。WebDriverに依存せず、HTTPプロキシ経由でブラウザを操作します。

// testcafe
import { Selector } from 'testcafe';

fixture`ログインテスト`.page`/login`;

test('ログインしてダッシュボードを表示', async t => {
  await t
    .typeText('#email', 'user@example.com')
    .typeText('#password', 'secret')
    .click('form button[type="submit"]')
    .expect(getLocation().pathname).contains('/dashboard');
});

🌐 ブラウザサポートと実行環境

cypress は当初Electron専用でしたが、現在はChrome、Edge、Firefoxをサポートしています。ただし、Safariやモバイルブラウザは非対応です。また、同一ドメイン外へのナビゲーション(例:OAuthフロー)には制限があります。

nightwatch はWebDriver準拠のため、Selenium Grid経由でほぼすべてのブラウザ(Chrome、Firefox、Safari、Edgeなど)をテストできます。クラウドテストサービス(BrowserStack、Sauce Labs)との連携も容易です。

puppeteer はChromium(またはChrome)専用です。他のブラウザをテストしたい場合は、Playwright(Puppeteerの後継プロジェクト)を検討する必要があります。

testcafe はWebDriverを使わず、独自のメカニズムでブラウザを操作するため、Chrome、Firefox、Safari、Edgeをネイティブにサポートしています。追加のドライバ設定不要で、複数ブラウザでの並列実行が可能です。

🔒 セキュリティとネットワーク制御

cypress はテストコードとアプリケーションが同一オリジンで実行されるため、CORSやCookieの扱いに注意が必要です。ただし、cy.intercept()でネットワークリクエストを簡単にモックできます。

// cypress: ネットワークリクエストのモック
cy.intercept('POST', '/api/login', { fixture: 'auth-success.json' }).as('login');
cy.get('form').submit();
cy.wait('@login');

nightwatch は標準のWebDriver APIを通じて動作するため、ネットワークモックには外部ツール(例:WireMock)やブラウザ拡張が必要です。直接的なリクエストインターセプト機能はありません。

puppeteerpage.setRequestInterception(true)を有効にすることで、リクエストやレスポンスを細かく制御できます。

// puppeteer: リクエストのインターセプト
await page.setRequestInterception(true);
page.on('request', interceptedRequest => {
  if (interceptedRequest.url().includes('/api/login')) {
    interceptedRequest.respond({
      status: 200,
      contentType: 'application/json',
      body: JSON.stringify({ token: 'fake-token' })
    });
  } else {
    interceptedRequest.continue();
  }
});

testcafeRequestMockクラスを使って、HTTPリクエストを簡単にモック・スタブできます。

// testcafe: リクエストモック
import { RequestMock } from 'testcafe';

const mock = RequestMock()
  .onRequestTo('http://localhost:3000/api/login')
  .respond({ token: 'fake-token' }, 200, { 'content-type': 'application/json' });

test.requestHooks(mock)('ログインAPIをモック', async t => {
  // ...
});

🛠️ デバッグと開発体験

cypress はタイムトラベリングデバッガを備え、テスト実行中のDOMスナップショットを再生できます。また、テストランナーUIが直感的で、失敗時のスクリーンショットや動画記録も標準でサポートされています。

nightwatch はCLI中心のツールで、GUIデバッガは提供していません。ただし、Seleniumのログやスクリーンショット機能を活用できます。

puppeteer はヘッドフルモードで実行すれば、実際のブラウザウィンドウを操作しながらデバッグ可能です。DevToolsとの連携も容易です。

testcafe はライブモード(--liveオプション)でテストを再実行せずに修正を反映でき、デバッグに便利です。また、失敗時に自動でスクリーンショットを保存します。

⚙️ 設定と拡張性

cypresscypress.config.jsで設定を管理し、プラグインシステムでカスタマイズ可能です。ただし、カスタムレポーターの統合には少し工夫が必要です。

nightwatchnightwatch.conf.jsで柔軟な設定が可能で、MochaやJasmineなどのテストランナーと統合できます。WebDriverの設定も詳細に制御できます。

puppeteer は単なるライブラリであり、テストフレームワークではありません。JestやMochaなど既存のテストランナーと組み合わせて使う必要があります。

testcafe は設定ファイル不要で即座にテストを書けますが、testcafe.config.jsで詳細設定も可能です。独自のテストランナーを内蔵しており、外部依存が少ないのが利点です。

📊 まとめ:各ツールの強みと適したケース

特徴cypressnightwatchpuppeteertestcafe
学習コスト低(初心者向け)高(プログラミング知識必要)
ブラウザサポートChrome/Firefox/Edge全ブラウザ(WebDriver経由)Chromium/Chromeのみ全主要ブラウザ(ネイティブ)
ネットワークモック組み込み(cy.intercept外部ツール必要プログラム制御可能組み込み(RequestMock
デバッグ体験優れている(タイムトラベル)標準的実ブラウザで直接操作ライブモードあり
CI/CD統合容易標準的容易(ただしChromium限定)容易

💡 最終的な判断基準

  • チームが初心者中心で、迅速に信頼性の高いテストを書きたいcypress
  • 複数ブラウザ(特にSafari)でのテストが必須で、Seleniumインフラがあるnightwatch
  • ブラウザ自動化そのものが目的(テスト以外の用途含む)で、Chromiumで十分puppeteer
  • WebDriverに依存せず、シンプルにマルチブラウザテストを始めたいtestcafe

どのツールも成熟しており、メンテナンスも継続されています。プロジェクトの要件(対象ブラウザ、チームスキル、インフラ)に最も合うものを選ぶことが成功の鍵です。

選び方: puppeteer vs cypress vs testcafe vs nightwatch
  • puppeteer:

    puppeteerは、E2EテストだけでなくPDF生成やスクリーンショット取得など、ブラウザ自動化全般が必要な場合に適しています。ChromiumまたはChromeのみで十分であれば、細かい制御が可能な低レベルAPIが魅力です。ただし、テストフレームワークではないため、JestやMochaなどと組み合わせる必要があります。マルチブラウザテストが必要なら、代わりにPlaywrightを検討すべきです。

  • cypress:

    cypressは、チームにテスト初心者が多く、迅速に信頼性の高いE2Eテストを構築したい場合に最適です。ChromeやFirefoxなど主要ブラウザでのテストが中心で、ネットワークモックやタイムトラベリングデバッガといった開発体験に優れた機能が必要なプロジェクトに向いています。ただし、Safariやモバイルブラウザのテスト、あるいは複雑なクロスドメイン認証フローがある場合は制限に注意が必要です。

  • testcafe:

    testcafeは、WebDriverに依存せず、追加設定なしで複数ブラウザでのテストをすぐに始めたい場合に最適です。SafariやEdgeを含む全主要ブラウザをネイティブにサポートし、ネットワークモックやライブデバッグといった開発者フレンドリーな機能も充実しています。CI/CD環境での安定性も高く、中規模以上のプロジェクトでバランスの取れた選択肢となります。

  • nightwatch:

    nightwatchは、既にSeleniumインフラを運用しており、Safariを含む幅広いブラウザでのテストが必須な環境で選ぶべきです。WebDriver標準に準拠しているため、BrowserStackやSauce Labsといったクラウドテストサービスとの連携も容易です。ただし、ネットワークモックには外部ツールが必要で、現代的な開発体験を求めるチームにはやや古めかしく感じられるかもしれません。

puppeteer のREADME

Puppeteer

build npm puppeteer package

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

Get started | API | FAQ | Contributing | Troubleshooting

Installation

npm i puppeteer # Downloads compatible Chrome during installation.
npm i puppeteer-core # Alternatively, install as a library, without downloading Chrome.

MCP

Install chrome-devtools-mcp, a Puppeteer-based MCP server for browser automation and debugging.

Example

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();