playwright vs puppeteer vs cypress vs nightwatch vs testcafe
E2Eテストおよびブラウザ自動化ツールの技術的比較
playwrightpuppeteercypressnightwatchtestcafe類似パッケージ:

E2Eテストおよびブラウザ自動化ツールの技術的比較

cypressnightwatchplaywrightpuppeteertestcafe はすべて、Webアプリケーションのエンドツーエンド(E2E)テストやブラウザ自動化を目的としたJavaScript/TypeScriptベースのツールです。これらは開発者がUIの動作をプログラムで検証し、回帰バグを防ぐために使用されます。各ツールは異なるアーキテクチャ、API設計、サポートブラウザ、デバッグ機能を持ち、プロジェクトの要件やチームのワークフローに応じて選択が分かれます。

npmのダウンロードトレンド

3 年

GitHub Starsランキング

統計詳細

パッケージ
ダウンロード数
Stars
サイズ
Issues
公開日時
ライセンス
playwright33,267,66884,5113.72 MB6101ヶ月前Apache-2.0
puppeteer7,342,08293,86663 kB2945日前Apache-2.0
cypress6,077,31149,6104.46 MB1,2135日前MIT
nightwatch122,74911,9531.94 MB3372ヶ月前MIT
testcafe09,9156.32 MB262ヶ月前MIT

Cypress vs Nightwatch vs Playwright vs Puppeteer vs TestCafe: ブラウザ自動化ツールの実践的比較

フロントエンド開発において、UIの信頼性を保つには強固なE2Eテスト戦略が不可欠です。しかし、cypressnightwatchplaywrightpuppeteertestcafe の5つの主要ツールは、それぞれ異なる哲学と技術的トレードオフを持っています。この記事では、実際のコード例を交えながら、各ツールの核心的な違いを掘り下げます。

🧪 テスト実行モデル:インブラウザ vs ドライバーベース vs プロキシベース

cypress はテストコードをブラウザ内で直接実行します。これにより、DOM操作やネットワークリクエストへの介入が極めて自然になります。

// cypress: ネットワークリクエストのモック
it('ログインAPIをモック', () => {
  cy.intercept('POST', '/api/login', { fixture: 'login-success.json' }).as('login');
  cy.visit('/login');
  cy.get('#email').type('user@example.com');
  cy.get('#password').type('pass');
  cy.get('form').submit();
  cy.wait('@login'); // モックされたレスポンスを待機
  cy.url().should('include', '/dashboard');
});

nightwatchSelenium WebDriver を介してブラウザを制御します。テストコードはNode.js上で実行され、HTTP経由でブラウザドライバーと通信します。

// nightwatch: 基本的なUI操作
module.exports = {
  'ログインテスト': function (browser) {
    browser
      .url('https://example.com/login')
      .setValue('#email', 'user@example.com')
      .setValue('#password', 'pass')
      .click('form button[type=submit]')
      .assert.urlContains('/dashboard')
      .end();
  }
};

playwright は各ブラウザベンダーと密接に連携し、ネイティブな自動化プロトコルを使用します。これにより、高速かつ安定した操作が可能になります。

// playwright: 複数ブラウザ対応のテスト
import { test, expect } from '@playwright/test';

test('ログイン成功', async ({ page }) => {
  await page.route('**/api/login', route => route.fulfill({
    json: { success: true, user: { id: 1 } }
  }));
  await page.goto('/login');
  await page.fill('#email', 'user@example.com');
  await page.fill('#password', 'pass');
  await page.click('form button[type=submit]');
  await expect(page).toHaveURL(/dashboard/);
});

puppeteer も同様にChromiumのDevTools Protocolを直接使用しますが、Chromium系ブラウザ専用です。

// puppeteer: 基本的な操作
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com/login');
  await page.type('#email', 'user@example.com');
  await page.type('#password', 'pass');
  await page.click('form button[type=submit]');
  await page.waitForNavigation();
  console.assert(page.url().includes('/dashboard'));
  await browser.close();
})();

testcafe独自のプロキシサーバーを介してブラウザと通信します。テストコードはNode.js上で実行されますが、ブラウザ内に挿入されたスクリプトが実際の操作を行います。

// testcafe: 直感的なAPI
import { Selector } from 'testcafe';

fixture`ログイン`
  .page`https://example.com/login`;

test('ログイン成功', async t => {
  await t
    .typeText('#email', 'user@example.com')
    .typeText('#password', 'pass')
    .click('form button[type=submit]')
    .expect(Selector('h1').innerText).eql('ダッシュボード');
});

🌐 ブラウザサポート範囲

  • cypress: Chromium系(Chrome, Edge)、Firefox(制限あり)。Safariは非対応。
  • nightwatch: WebDriver対応ブラウザすべて(Chrome, Firefox, Safari, Edge)。
  • playwright: Chromium、WebKit(Safari)、Firefox をフルサポート。各ブラウザの最新版だけでなく、特定バージョンも指定可能。
  • puppeteer: Chromium系のみ(Chrome, Edge)。Firefoxサポートは実験的で非推奨。
  • testcafe: Chrome, Firefox, Safari, Edge をサポート。内部でWebDriverやプロキシを自動選択。

Playwrightは唯一、Safari(WebKit)を本格的にサポートする現代的ツールです。

🔌 ネットワーク操作とモックの柔軟性

cypressplaywright はネットワークのインターセプトとモックが非常に洗練されています。

// cypress: レスポンスの遅延やステータスコード変更
cy.intercept({
  method: 'GET',
  url: '/api/user',
}, {
  statusCode: 500,
  body: { error: 'Server down' }
});
// playwright: 同様の機能
await page.route('**/api/user', route => route.fulfill({
  status: 500,
  body: JSON.stringify({ error: 'Server down' })
}));

一方、puppeteerpage.setRequestInterception(true) を有効にする必要があり、コードが冗長になります。

// puppeteer: リクエストインターセプト
await page.setRequestInterception(true);
page.on('request', interceptedRequest => {
  if (interceptedRequest.url().includes('/api/user')) {
    interceptedRequest.respond({
      status: 500,
      body: JSON.stringify({ error: 'Server down' })
    });
  } else {
    interceptedRequest.continue();
  }
});

nightwatchtestcafe はネットワークモックのサポートが限定的です。NightwatchはSeleniumの制約を受け、TestCafeは基本的なモックのみ提供します。

⚙️ 設定と初期導入の手間

  • cypress: npx cypress open で即時起動。設定ファイルは最小限。
  • nightwatch: Seleniumサーバーやブラウザドライバーのインストールが必要。nightwatch.conf.js の設定が複雑。
  • playwright: npx playwright install で全ブラウザを一括インストール。設定は直感的。
  • puppeteer: npm install puppeteer だけでChromiumが自動ダウンロード。追加設定不要。
  • testcafe: npm install testcafe で完了。テストファイルを書くだけで実行可能。

TestCafeとPuppeteerはゼロコンフィグに近い体験を提供しますが、Nightwatchは最も設定が面倒です。

📸 ビジュアルテストとスクリーンショット

playwright はビジュアルリグレッションテストを組み込みサポートしています。

// playwright: スナップショットテスト
import { test, expect } from '@playwright/test';

test('UIスナップショット', async ({ page }) => {
  await page.goto('/');
  await expect(page).toHaveScreenshot('homepage.png');
});

cypress は公式プラグイン(cypress-plugin-snapshots)経由で対応可能ですが、標準機能ではありません。

puppeteer はスクリーンショット取得は可能ですが、差分検出は自前実装が必要です。

// puppeteer: スクリーンショット
await page.screenshot({ path: 'screenshot.png' });

NightwatchとTestCafeはビジュアルテストのサポートが弱いです。

🔄 非同期処理の扱い方

cypress は独自のコマンドキューを使用するため、Promiseチェーンやasync/awaitとは異なる記述が必要です。

// cypress: コマンドチェーン(async/await不可)
cy.get('#button').click().then(() => {
  // 別の操作
});

一方、playwrightpuppeteertestcafe は標準的なasync/await を全面的にサポートします。

// playwright: 標準的なasync/await
await page.click('#button');
const text = await page.textContent('#result');

Nightwatchはコールバックまたはasync/awaitの両方をサポートしますが、一貫性に欠けることがあります。

🛑 デバッグと開発体験(DX)

  • cypress: テスト実行中のタイムトラベルデバッグが最大の強み。各ステップのDOM状態を再生可能。
  • playwright: VS Code拡張によるインタラクティブデバッグ、テストジェネレーター、トレースビューアを提供。
  • testcafe: テスト失敗時に自動でスクリーンショットとコンソールログを保存。
  • puppeteer: DevToolsを直接開いてデバッグ可能(headless: false 時)。
  • nightwatch: デバッグ機能は限定的。主にログ出力に依存。

CypressとPlaywrightは、現代的なDXを最も重視した設計になっています。

📊 まとめ:各ツールの強みと用途

ツール最適なユースケース主な制限
cypress開発体験重視、Chromium/Firefox中心のプロジェクト単一オリジン制限、複数タブ非対応
nightwatch既存Selenium環境との統合、レガシーインフラ設定が複雑、現代的機能が不足
playwright複数ブラウザ対応、高度な自動化、大規模テスト学習曲線がやや急
puppeteerChromium専用の自動化、スクレイピング、PDF生成ブラウザサポートが限定的
testcafeクイックスタート、WebDriver不要のシンプルテストエコシステムが小規模

💡 最終的な判断基準

  • 「すぐに始めたい、設定は最小限に」testcafe または puppeteer(Chromium限定なら)
  • 「最高の開発体験とデバッグ機能が欲しい」cypress
  • 「Safari含む全ブラウザで信頼性の高いテストが必要」playwright
  • 「既存のSeleniumインフラがある」nightwatch(ただし新規プロジェクトでは避けるべき)

現代的なフロントエンド開発では、playwright が最もバランスの取れた選択肢となっています。一方、cypress はDXを最優先するチームにとって依然として魅力的です。プロジェクトのスケール、ブラウザ要件、メンテナンスコストを総合的に考慮して選んでください。

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

  • playwright:

    playwrightは、Microsoftが開発する最新世代のブラウザ自動化ライブラリで、Chromium、WebKit、Firefoxをネイティブにサポートします。ネットワークモック、ビジュアルテスト、モバイルエミュレーションなど高度な機能を備え、並列実行や信頼性の高いテストも容易です。大規模プロジェクトや複数ブラウザ対応が必要なケース、あるいはPuppeteerの後継としての利用を検討しているチームにおすすめです。

  • puppeteer:

    puppeteerはGoogleが開発するChromium専用のNode.jsライブラリで、主にスクレイピング、PDF生成、パフォーマンス計測などの自動化タスクに使われます。E2Eテストにも使えますが、公式にはChromium系ブラウザのみをサポートしており、FirefoxやSafariのテストには不向きです。シンプルな自動化スクリプトや、Chromium限定のテストが必要な場合に適しています。

  • cypress:

    cypressは、開発体験(DX)とデバッグのしやすさを重視するチームに最適です。テストコードがブラウザ内で直接実行されるため、ネットワークリクエストのモックやタイムトラベルデバッグが直感的に行えます。ただし、単一のオリジン(同一ドメイン)に制限され、複数タブや複数ブラウザ間の操作には対応していません。CI環境での安定性とローカル開発の親和性が高いプロジェクトに向いています。

  • nightwatch:

    nightwatchはWebDriverプロトコルに基づく古典的なE2Eテストフレームワークで、Seleniumサーバー経由でブラウザを制御します。既存のSeleniumインフラと統合したい場合や、複数ブラウザ・OSでのクロスブラウザテストが必要なレガシープロジェクトに適しています。ただし、現代的なツールと比べて設定が煩雑で、開発体験が劣ることがあります。新しいプロジェクトでは慎重に検討すべきです。

  • testcafe:

    testcafeは独自のプロキシベースのアーキテクチャにより、ブラウザ拡張や外部ドライバーなしにテストを実行できます。セットアップが非常に簡単で、TypeScriptサポートも組み込み済みです。ただし、コミュニティ規模やエコシステムの成熟度はPlaywrightやCypressに劣ります。素早くテスト基盤を立ち上げたい小〜中規模チームや、Selenium依存を避けたいプロジェクトに向いています。

playwright のREADME

🎭 Playwright

npm version Chromium version Firefox version WebKit version Join Discord

Documentation | API reference

Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API. Playwright is built to enable cross-browser web automation that is ever-green, capable, reliable, and fast.

LinuxmacOSWindows
Chromium 145.0.7632.6:white_check_mark::white_check_mark::white_check_mark:
WebKit 26.0:white_check_mark::white_check_mark::white_check_mark:
Firefox 146.0.1:white_check_mark::white_check_mark::white_check_mark:

Headless execution is supported for all browsers on all platforms. Check out system requirements for details.

Looking for Playwright for Python, .NET, or Java?

Installation

Playwright has its own test runner for end-to-end tests, we call it Playwright Test.

Using init command

The easiest way to get started with Playwright Test is to run the init command.

# Run from your project's root directory
npm init playwright@latest
# Or create a new project
npm init playwright@latest new-project

This will create a configuration file, optionally add examples, a GitHub Action workflow and a first test example.spec.ts. You can now jump directly to writing assertions section.

Manually

Add dependency and install browsers.

npm i -D @playwright/test
# install supported browsers
npx playwright install

You can optionally install only selected browsers, see install browsers for more details. Or you can install no browsers at all and use existing browser channels.

Capabilities

Resilient • No flaky tests

Auto-wait. Playwright waits for elements to be actionable prior to performing actions. It also has a rich set of introspection events. The combination of the two eliminates the need for artificial timeouts - a primary cause of flaky tests.

Web-first assertions. Playwright assertions are created specifically for the dynamic web. Checks are automatically retried until the necessary conditions are met.

Tracing. Configure test retry strategy, capture execution trace, videos and screenshots to eliminate flakes.

No trade-offs • No limits

Browsers run web content belonging to different origins in different processes. Playwright is aligned with the architecture of the modern browsers and runs tests out-of-process. This makes Playwright free of the typical in-process test runner limitations.

Multiple everything. Test scenarios that span multiple tabs, multiple origins and multiple users. Create scenarios with different contexts for different users and run them against your server, all in one test.

Trusted events. Hover elements, interact with dynamic controls and produce trusted events. Playwright uses real browser input pipeline indistinguishable from the real user.

Test frames, pierce Shadow DOM. Playwright selectors pierce shadow DOM and allow entering frames seamlessly.

Full isolation • Fast execution

Browser contexts. Playwright creates a browser context for each test. Browser context is equivalent to a brand new browser profile. This delivers full test isolation with zero overhead. Creating a new browser context only takes a handful of milliseconds.

Log in once. Save the authentication state of the context and reuse it in all the tests. This bypasses repetitive log-in operations in each test, yet delivers full isolation of independent tests.

Powerful Tooling

Codegen. Generate tests by recording your actions. Save them into any language.

Playwright inspector. Inspect page, generate selectors, step through the test execution, see click points and explore execution logs.

Trace Viewer. Capture all the information to investigate the test failure. Playwright trace contains test execution screencast, live DOM snapshots, action explorer, test source and many more.

Looking for Playwright for TypeScript, JavaScript, Python, .NET, or Java?

Examples

To learn how to run these Playwright Test examples, check out our getting started docs.

Page screenshot

This code snippet navigates to Playwright homepage and saves a screenshot.

import { test } from '@playwright/test';

test('Page Screenshot', async ({ page }) => {
  await page.goto('https://playwright.dev/');
  await page.screenshot({ path: `example.png` });
});

Mobile and geolocation

This snippet emulates Mobile Safari on a device at given geolocation, navigates to maps.google.com, performs the action and takes a screenshot.

import { test, devices } from '@playwright/test';

test.use({
  ...devices['iPhone 13 Pro'],
  locale: 'en-US',
  geolocation: { longitude: 12.492507, latitude: 41.889938 },
  permissions: ['geolocation'],
})

test('Mobile and geolocation', async ({ page }) => {
  await page.goto('https://maps.google.com');
  await page.getByText('Your location').click();
  await page.waitForRequest(/.*preview\/pwa/);
  await page.screenshot({ path: 'colosseum-iphone.png' });
});

Evaluate in browser context

This code snippet navigates to example.com, and executes a script in the page context.

import { test } from '@playwright/test';

test('Evaluate in browser context', async ({ page }) => {
  await page.goto('https://www.example.com/');
  const dimensions = await page.evaluate(() => {
    return {
      width: document.documentElement.clientWidth,
      height: document.documentElement.clientHeight,
      deviceScaleFactor: window.devicePixelRatio
    }
  });
  console.log(dimensions);
});

Intercept network requests

This code snippet sets up request routing for a page to log all network requests.

import { test } from '@playwright/test';

test('Intercept network requests', async ({ page }) => {
  // Log and continue all network requests
  await page.route('**', route => {
    console.log(route.request().url());
    route.continue();
  });
  await page.goto('http://todomvc.com');
});

Resources