Playwright vs Cypress 比較

Microsoftによるマルチブラウザ・多言語対応のE2Eテストエンジン

VS
Cypress

ブラウザ内で動作する、開発者体験重視のJS/TS E2Eツール

16 分で読了ツール

クイック結論

明確な唯一の正解はないが、明確な判断基準はある。マルチブラウザ対応、無料の並列実行、cross-origin/iframeフロー、あるいはJS/TS以外の言語が必要なら、Playwrightが2026年のデフォルトの選択肢だ。 広範で健全なCypressスイートとCloudへの投資が既にあるなら、単なる「ツールの違い」だけでは書き直しは正当化されない — component testingにおいてはCypressの方が今日時点で成熟している。段階的で重要フロー優先の移行の方が「週末で書き直す」よりも合理的だ。

PlaywrightCypress
結論をすべて読む

スコア比較

グラフを読み込み中...

詳細スコア

詳細スコア: Playwright Cypress — カテゴリー別10点満点のスコア
カテゴリーPlaywrightCypress
パフォーマンス
8/10
7/10
学習のしやすさ
7/10
8/10
エコシステム
8/10
7/10
コミュニティ
8/10
7/10
求人市場
7/10
7/10
将来性
9/10
6/10

長所と短所

Playwright

長所

  • Chromium、Firefox、WebKitを単一のAPIでサポート
  • 組み込みで完全無料の並列workerモデル
  • cross-origin、iframe、複数タブをアーキテクチャとしてネイティブサポート
  • JS/TSに加えて公式のPython、Java、.NETバインディング
  • Trace ViewerでDOM/ARIA/スクリーンショットのスナップショットを並べて確認できる(v1.63)
  • Test Locksで共有リソースを安全に扱える(v1.63)
  • Apache-2.0ライセンス、コアは完全に無料でオープンソース
  • 追加設定不要でネットワークモックができるroute() API

短所

  • ブラウザ内の「Time Travel」の感覚はCypressほど自然ではない
  • component testingパッケージ(@playwright/experimental-ct-*)が廃止され、アーキテクチャ移行の過程にある
  • 多言語サポートは、チームにとって言語ごとの学習コストを複雑にする可能性がある
  • 公式の顧客/事例紹介ページがなく、ROIの証拠を得るにはサードパーティのソースを参照する必要がある
  • 有料クラウドサービス(Azure App Testing)の料金は透明に公開されていない

最適な用途

マルチブラウザ(特にWebKit/Safari)の検証が必要なプロダクトcross-origin/SSO、iframe中心の決済フローを持つアプリケーションJS/TS以外にPython/Java/.NETのテストエンジニアがいるチーム大規模CIで無料の並列実行を求めるチーム新規・グリーンフィールドのE2Eスイート構築

Cypress

長所

  • Time Travelデバッグとおなじみのdev toolsによる自然な開発者体験
  • インタラクティブなrunnerにより、ほぼゼロに近い導入障壁(JS/TSを知るチームにとって)
  • component testingにおけるReact/Vue/Angular/Svelte向けの公式で成熟したアダプター
  • Cypress CloudのTest ReplayでCIの失敗を忠実に再現できる
  • 公式の顧客事例(Indeed):テスト時間58%削減、デバッグ時間50%削減
  • cy.intercept()による豊富なネットワークstub/assertion API
  • オープンソースのAppは完全無料(MIT)
  • learn.cypress.ioによる無料の公式インタラクティブトレーニング

短所

  • same-originのアーキテクチャ制約 — cross-originテストにはcy.origin()が必要
  • WebKitサポートは依然として「Experimental」ステータス
  • JavaScript/TypeScriptのみ — 他言語のバインディングはない
  • 並列実行はCypress Cloudへの記録(--record)に依存; auto cancellationとspec prioritizationはBusinessプラン以上
  • 16.0.0は最初の2週間で4件の回帰修正を必要とした(うち3件はネイティブネットワークパスに関連)
  • Node.js 20/25ではもう動作しない — CIでのNodeバージョン管理が必須

最適な用途

広範で健全に稼働している既存のCypressスイートを持つチームcomponent testing中心のReact/Vue/Angular/SvelteプロジェクトJS/TSのみのチーム、言語の多様性を必要としないチームブラウザ内でのインタラクティブなデバッグ習慣が根付いたチームCypress Cloud(Test Replay、レポート機能)に既に投資している組織

コード比較

Playwright
// Playwright Test - ログインフローとAPIモック(TypeScript)
import { test, expect } from '@playwright/test';

test.describe('Giris akisi', () => {
  test('gecerli kullanici ile giris yapar ve dashboard gorur', async ({ page }) => {
    // ネットワークモック - 追加設定不要
    await page.route('**/api/login', async (route) => {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({ token: 'test-token', user: { name: 'Ayse' } }),
      });
    });

    await page.goto('/login');
    await page.getByLabel('E-posta').fill('[email protected]');
    await page.getByLabel('Sifre').fill('guclu-sifre-123');
    await page.getByRole('button', { name: 'Giris Yap' }).click();

    // Auto-wait: ロケーターが表示されるまで待機
    await expect(page.getByText('Hos geldin, Ayse')).toBeVisible();
    await expect(page).toHaveURL('/dashboard');
  });

  test('checkout iframe icindeki odeme butonunu bulur (cross-frame)', async ({ page }) => {
    await page.goto('/checkout');

    // v1.63.0: セレクターなしのframeLocatorはすべてのサブフレームツリーを検索
    const payButton = page.frameLocator().getByRole('button', { name: 'Ode' });
    await payButton.click();

    await expect(page.getByText('Odeme basarili')).toBeVisible();
  });
});

test('3 tarayicida paralel calisir (playwright.config.ts icinde tanimli)', async ({ page }) => {
  await page.goto('/');
  await expect(page).toHaveTitle(/Ana Sayfa/);
});
Cypress
// Cypress - ログインフローとAPIモック(JavaScript/TypeScript)
describe('Giris akisi', () => {
  it('gecerli kullanici ile giris yapar ve dashboard gorur', () => {
    // cy.interceptによるネットワークスタブ
    cy.intercept('POST', '/api/login', {
      statusCode: 200,
      body: { token: 'test-token', user: { name: 'Ayse' } },
    }).as('loginRequest');

    cy.visit('/login');
    cy.get('[data-cy=email]').type('[email protected]');
    cy.get('[data-cy=password]').type('guclu-sifre-123');
    cy.get('[data-cy=submit]').click();

    cy.wait('@loginRequest');

    // Cypress自動リトライ: 要素が表示されるまで待機
    cy.contains('Hos geldin, Ayse').should('be.visible');
    cy.url().should('include', '/dashboard');
  });

  it('cross-origin odeme sayfasina yonlenir (cy.origin gerekli)', () => {
    cy.visit('/checkout');
    cy.get('[data-cy=pay-button]').click();

    // 異なるoriginに移動する際はcy.origin()が必須
    cy.origin('https://pay.example.com', () => {
      cy.get('[data-cy=confirm-payment]').click();
      cy.contains('Odeme onaylandi').should('be.visible');
    });
  });
});

// cypress.config.js — 基本的なE2E設定
module.exports = {
  e2e: {
    baseUrl: 'http://localhost:3000',
    experimentalRunAllSpecs: true,
    setupNodeEvents(on, config) {
      return config;
    },
  },
};

結論

明確な唯一の正解はないが、明確な判断基準はある。マルチブラウザ対応、無料の並列実行、cross-origin/iframeフロー、あるいはJS/TS以外の言語が必要なら、Playwrightが2026年のデフォルトの選択肢だ。 広範で健全なCypressスイートとCloudへの投資が既にあるなら、単なる「ツールの違い」だけでは書き直しは正当化されない — component testingにおいてはCypressの方が今日時点で成熟している。段階的で重要フロー優先の移行の方が「週末で書き直す」よりも合理的だ。

無料相談を受ける
FAQ

よくある質問

マルチブラウザ(Chromium+Firefox+WebKit)が必要な場合、無料の組み込み並列実行を求める場合、またはTS/Python/Java/.NET間の言語の柔軟性が必要な場合は、Playwrightが2026年のデフォルトの選択肢だ。既に広範なCypressスイートがあり、チームがインタラクティブなrunnerに慣れていて、Cypress Cloudに既に投資しているなら、単なる「ツールの違い」だけで移行は正当化されない — 段階的な移行の方が合理的だ。

関連ブログ記事

すべての記事を見る
すべての比較