> 九號工具站
返回列表

Cypress 入門 + vs Playwright 完整對比 — 該選哪個 + 遷移實戰

Cypress 完整入門 + 跟 Playwright 的真實對比。架構差異、Selector 哲學、Cross-origin / Multi-tab / 並行、生態系、價格、何時該選 / 何時該遷。

QA cypress playwright e2e framework-comparison migration
· 最後更新 2026-06-17 · 最後審閱 2026-08-30

💡 本文原刊於 qa.9niche.com,2026-08 併入 9niche.com 懶人包,內容照原文完整搬遷。

1. 前言

「我們公司用 Cypress、面試問 Playwright 我不會、該轉嗎?」 — 看到太多 QA 卡在這。實話:Cypress 還很好用、但 Playwright 全方位贏。這篇講清楚兩者差異 + 何時該轉。

2. 一張圖看完差異

flowchart TD Choose{選 framework} --> Q1{多瀏覽器?} Q1 -->|Chrome only| Cyp1[Cypress 可] Q1 -->|Safari / WebKit| PW1[Playwright] Choose --> Q2{Cross-origin?} Q2 -->|不需要| Cyp2[Cypress 可] Q2 -->|要 OAuth / 多 domain| PW2[Playwright] Choose --> Q3{多 tab / iframe?} Q3 -->|不需要| Cyp3[Cypress 可] Q3 -->|要| PW3[Playwright] Choose --> Q4{平行跑 CI 預算?} Q4 -->|沒限制| Both[都行] Q4 -->|要免費| PW4[Playwright] style PW1 fill:#10b981,color:#fff style PW2 fill:#10b981,color:#fff style PW3 fill:#10b981,color:#fff style PW4 fill:#10b981,color:#fff style Cyp1 fill:#06b6d4,color:#fff style Cyp2 fill:#06b6d4,color:#fff style Cyp3 fill:#06b6d4,color:#fff

3. Cypress 30 分鐘入門

安裝

npm init -y
npm install --save-dev cypress
npx cypress open

GUI 介面選「E2E Testing」、Cypress 會自動建好 demo。

第一個 test

// cypress/e2e/login.cy.js
describe('Login', () => {
  beforeEach(() => {
    cy.visit('https://app.example.com/login');
  });

  it('登入成功跳轉 dashboard', () => {
    cy.get('input[name=email]').type('[email protected]');
    cy.get('input[name=password]').type('Test@123');
    cy.contains('button', '登入').click();
    cy.url().should('include', '/dashboard');
    cy.contains('Welcome').should('be.visible');
  });

  it('錯密碼顯示錯誤', () => {
    cy.get('input[name=email]').type('[email protected]');
    cy.get('input[name=password]').type('wrong');
    cy.contains('button', '登入').click();
    cy.contains('帳號或密碼錯誤').should('be.visible');
  });
});

跑:

npx cypress run                  # headless
npx cypress run --browser chrome # 指定瀏覽器
npx cypress open                 # GUI 互動

Cypress 最大強項 — Time Travel Debugger

這個 UX 至今沒對手。Playwright trace viewer 接近但體驗仍差一截。

flowchart LR Tests[跑 test] --> Snap[每步 snapshot DOM] Snap --> GUI[GUI 介面] GUI --> Click[點任一步 → 看當下 DOM] Click --> Console[Console 直接 query] style GUI fill:#a855f7,color:#fff style Console fill:#10b981,color:#fff

4. Cypress vs Playwright 全方位對比

維度CypressPlaywright贏家
學習曲線低(chainable API 直覺)中(async/await 標準)Cypress
Debug UX神級 time travel好的 trace viewerCypress
多瀏覽器Chrome / Edge / Firefox+ WebKit (Safari)Playwright
Cross-origin受限(需 setting)原生支援Playwright
Multi-tab / window困難 / hack原生Playwright
iframe困難原生 page.frame()Playwright
平行測試要付費 Cypress Cloud免費內建 shardingPlaywright
API 測試cy.request()request fixture平手
Component testingCypress
Mobile emulation受限Playwright
Auto-wait平手
TypeScript支援一等公民Playwright
CI 整合更好Playwright
企業支援Cypress CloudMicrosoft 支持Playwright
社群活躍大但減暴增中Playwright
NPM downloads5M/week12M/week (2026)Playwright

5. Selector 哲學差異

// Cypress — chainable + 自家 API
cy.get('button')
  .contains('Submit')
  .click();

cy.get('[data-testid=email]')
  .type('[email protected]');

// Playwright — standard async/await
await page.getByRole('button', { name: 'Submit' }).click();
await page.getByLabel('Email').fill('[email protected]');

Playwright 用 getByRole 跟 accessibility tree 走、跨 UI 改動更穩Cypress 鼓勵 data-testid、要前端配合

6. Cross-origin 痛點實戰

// Cypress — OAuth 登入會死
it('OAuth login', () => {
  cy.visit('/login');
  cy.contains('Sign in with Google').click();
  // ❌ 跳到 accounts.google.com → cy.url() fail
  // 需要 cy.origin() 或 mock 整段 flow
});

// Playwright — 沒事
test('OAuth login', async ({ page }) => {
  await page.goto('/login');
  await page.click('text=Sign in with Google');
  await page.fill('input[type=email]', '[email protected]');
  await page.click('button:has-text("Next")');
  // ✓ 跨域沒問題
});

OAuth 工作流 = Playwright 絕對選

7. Component Testing — Cypress 還領先

// Cypress + React component test
import Button from './Button';

describe('Button', () => {
  it('renders text', () => {
    cy.mount(<Button>Click me</Button>);
    cy.contains('Click me').should('be.visible');
  });

  it('handles click', () => {
    const onClick = cy.stub();
    cy.mount(<Button onClick={onClick}>Click</Button>);
    cy.contains('Click').click();
    cy.wrap(onClick).should('have.been.calledOnce');
  });
});

這塊 Cypress UX 還是最好。但新案推 Vitest + Testing Library(更快、更輕量)。

8. 平行測試 — Cypress 收費痛

Cypress 平行測試需要 Cypress Cloud 訂閱。150 個 case 跑 30 分鐘、付費後變 8 分鐘 — 但每月 $75 起跳。 Playwright --shard=1/4 免費就有

flowchart LR PW[Playwright] -->|內建免費| PWS[--shard=N/4] PWS --> Free[$0] Cy[Cypress] --> CC{Cypress Cloud?} CC -->|是| Pay["$75 / month start"] CC -->|否| Slow[全部 serial 跑] style Free fill:#10b981,color:#fff style Pay fill:#ef4444,color:#fff style Slow fill:#f59e0b,color:#fff

9. 遷移 Cypress → Playwright 實戰

Step 1: 評估

Step 2: API 對照表

CypressPlaywright
cy.visit(url)await page.goto(url)
cy.get(sel).click()await page.click(sel)
cy.get(sel).type(val)await page.fill(sel, val)
cy.contains(text)await page.getByText(text)
cy.url().should('include')await expect(page).toHaveURL()
cy.intercept('POST', url)await page.route(url)
cy.fixture('users.json')import users from './users.json'
cy.task('db:reset')直接呼叫 helper function
beforeEach()test.beforeEach()

Step 3: codemod 工具

npx playwright-codemod-cypress ./cypress/e2e/

會幫你轉 80%、剩 20% 手工

Step 4: 跑舊新平行 1-2 週

確認 case behavior 一致、再下架 Cypress。

flowchart TD Eval[評估] --> Q1{case 數 < 100?} Q1 -->|是| Big[全部重寫快] Q1 -->|否| Q2[漸進] Q2 --> S1[新 case 用 Playwright] S1 --> S2[舊 case 慢慢轉] S2 --> S3[Cypress 停止接受 new case] style Big fill:#10b981,color:#fff style S2 fill:#06b6d4,color:#fff

10. 反模式 — Cypress 該換的訊號

任 3 個 → 啟動遷移討論

flowchart TD Sig{該換訊號} --> S1["每天遇 cy.origin 卡關"] Sig --> S2["想測 Safari / iPad"] Sig --> S3["Cypress Cloud 月費 > $200"] Sig --> S4["跑 E2E > 30 分鐘"] Sig --> S5["平行常常 flaky"] Sig --> S6["招新人都會 Playwright 不會 Cypress"] Sig --> S7["AI workflow 工具都支援 Playwright"] style S1 fill:#ef4444,color:#fff style S2 fill:#ef4444,color:#fff style S3 fill:#ef4444,color:#fff style S4 fill:#ef4444,color:#fff style S5 fill:#ef4444,color:#fff style S6 fill:#ef4444,color:#fff style S7 fill:#ef4444,color:#fff

11. 面試常考題

Q1: Cypress 跟 Playwright 差別?

好答案(30 秒版):

Cypress 是 chainable API、time travel debugger 神級、Chrome-only 體驗最好。Playwright 是 async/await 標準、原生 cross-origin / multi-tab / 多瀏覽器 / 免費平行。新案推 Playwright、舊 Cypress 案不一定要遷。

Q2: 你會選哪個?

好答案

看情境。新案 90% 選 Playwright(多平台 + 免費平行)。Component testing 有時保留 Cypress。但團隊現在大多走 Playwright + Vitest 組合、Cypress 漸式微。

Q3: Cypress 如何處理 cross-origin?

好答案

cy.origin('https://other.com', () => { ... })、但仍有 cookie 限制與環境變數設置麻煩。Playwright 原生支援、寫起來像同 domain。

12. 給仍在 Cypress 的人

不要急著遷。但:
1. 學 Playwright(找工作必備)
2. 新 case 開始用 Playwright
3. 舊 case 維持 Cypress 直到痛點累積
4. 痛了再 codemod 遷

兩個都會的 QA = 求職市場熱門。

13. 最後

Cypress 是好工具、time travel UX 至今沒對手。但整體生態 + 跨平台支援 + 免費平行 → Playwright 全方位贏。2026 年的新案沒理由選 Cypress、但 5 年的 Cypress 案也不用急遷。會兩個 = 最強

延伸:

ℹ️

一般聲明

本站提供之資訊僅供參考,不保證其完整性與正確性。使用者應自行判斷資訊之適用性。

意見反饋