Playwright 入門 — 從 0 到第一個能跑的 E2E(30 分鐘上手)
Playwright 安裝、第一個測試、Selectors 選擇策略、debug 技巧、CI 整合。給有測試經驗但沒寫過自動化的 QA。
💡 本文原刊於 qa.9niche.com,2026-08 併入 9niche.com 懶人包,內容照原文完整搬遷。
目錄
1. 前言
如果你已經會寫手動 test case,學 Playwright 就是把同樣的步驟用 code 寫出來。難點不在 API,在「怎麼選元素」跟「怎麼等對的東西」。
2. 為什麼選 Playwright
| 對手 | 弱點 |
|---|---|
| Selenium | API 老派、wait 很麻煩、要自己裝 driver |
| Cypress | 只支援 Chromium、沒 multi-tab、跨 origin 麻煩 |
| Puppeteer | 純 Chromium、沒測試 runner |
Playwright 強項:原生支援 Chromium/Firefox/WebKit、auto-wait、trace viewer 神器、TypeScript 一等公民。新案直接選它。
3. 30 分鐘從 0 到 1
1. 安裝(2 分鐘)
npm init -y
npm init playwright@latest
CLI 會問你:
- TypeScript or JavaScript?→ TypeScript(型別檢查抓 bug)
- 測試放哪?→ 預設
tests/ - GitHub Actions workflow?→ Yes(之後就有 CI 模板)
- Install browsers?→ Yes
裝完看到 tests/example.spec.ts 跟 playwright.config.ts 就成功。
2. 跑第一個範例(1 分鐘)
npx playwright test
跑完開報告:
npx playwright show-report
3. 寫自己的測試(10 分鐘)
新增 tests/login.spec.ts:
import { test, expect } from '@playwright/test';
test('登入失敗顯示錯誤訊息', async ({ page }) => {
await page.goto('https://yourapp.com/login');
await page.getByLabel('Email').fill('[email protected]');
await page.getByLabel('Password').fill('wrong-password');
await page.getByRole('button', { name: '登入' }).click();
await expect(page.getByText('帳號或密碼錯誤')).toBeVisible();
});
跑:
npx playwright test login.spec.ts
恭喜,第一支跑起來了。
4. Selector 怎麼選(最關鍵)
新手最常犯的錯:用 CSS selector .btn-primary。class 改了測試就壞。
優先順序:
getByRole— 最穩,跟著無障礙樹走,UI 怎麼改都對page.getByRole('button', { name: '送出' })getByLabel— 表單欄位首選page.getByLabel('使用者名稱')getByText— 純文字內容page.getByText('購物車(3)')getByTestId— 上面都不行才用,且要跟前端團隊約好data-testid規範page.getByTestId('checkout-button')
禁忌:page.locator('.css-1a2b3c')(CSS-in-JS 雜湊每次 build 都變)、page.locator('div > div:nth-child(3) > button')(DOM 微調就壞)。
5. Auto-wait — 不用自己寫 sleep
// ❌ 舊習慣
await page.waitForTimeout(2000);
await page.click('.button');
// ✅ Playwright 寫法
await page.getByRole('button', { name: '送出' }).click();
// Playwright 自動等到元素:可見、enabled、stable、能被點擊
expect() 也自動 retry:
await expect(page.getByText('訂單已建立')).toBeVisible({ timeout: 10000 });
// 預設 5 秒內每 100ms retry 一次
結論:忘掉 sleep,用 expect.toBeVisible() 等狀態。
6. Debug 三神器
--headed— 看著瀏覽器跑npx playwright test --headed --workers=1--debug— Playwright Inspector,逐步執行npx playwright test login.spec.ts --debug- Trace Viewer — fail 後重現
# playwright.config.ts 設定 trace: 'on-first-retry' npx playwright show-trace trace.zipTrace viewer 會錄下每步的 DOM snapshot、network、console,比影片有用十倍。
7. CI 整合(GitHub Actions)
init 已幫你生 .github/workflows/playwright.yml:
name: Playwright Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: npm ci
- run: npx playwright install --with-deps
- run: npx playwright test
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 7
PR 提交就跑、fail 上傳 report、點下載就能 debug。
8. 新手避雷
- 不要每個 test 都
goto— 用beforeEach或storageState重用登入。 - 不要測 third-party 細節 — 別把 Google OAuth 內頁也寫進去,會被改死。
- selector 用 page object 包起來 — 5 個檔案以上就抽
LoginPageclass,selector 改一處就好。 - flaky test 不要忽略 — 通常是 race condition,加 retry 只是蓋住問題。
- 跨瀏覽器先別開全 — 起步先 Chromium,等穩定再加 Firefox/WebKit。
9. 下一步
- 學
fixtures重用登入狀態 - 學
expect(page).toHaveScreenshot()做視覺迴歸 - 學
requestAPI 直接打 API 不開瀏覽器(測 API + UI 混合)
學會選 selector + 用 auto-wait + 看懂 trace,你就會用 Playwright 了。剩下都是熟練度。
相關連結
Cypress 完整入門 + 跟 Playwright 的真實對比。架構差異、Selector 哲學、Cross-origin / Multi-tab / 並行、生態系、價格、何時該選 / 何時該遷。
從零配出 production-ready 的 Playwright CI。完整 yml、失敗截圖/trace 自動上傳、PR 自動留言報告、平行 sharding 加速。
POM 完整指南。為什麼用、怎麼拆 class、Playwright 實作範例、Component Object 進階、反模式。附類別關係圖與重構流程。
相關懶人包
2026 QA 趨勢實戰:我看到的 5 個轉變(AI、Shift-Left、Observability)
從手動 QA 到 AI 輔助、從測試金字塔到測試獎盃。這篇分享我這 10+ 年看 QA 從「測完才知道」到「shift-left + AI」的真實觀察。
2026 QA 面試的 AI 題 — 12 題 + 答題框架(面試官想聽什麼)
2026 QA 面試新增一整類「你怎麼用 AI」的問題。這篇整理 12 個高頻 AI 面試題、每題附面試官真正想聽的點與答題框架,從「你用過哪些 AI 工具」到「AI 生的 test 怎麼信任」。
AI / LLM 功能 Spec Review — 幻覺 / 評估 / 成本 / 法遵 8 個必問
AI 功能 spec review 完整指南。LLM 不確定性處理、評估指標、Prompt versioning、成本控制、安全護欄、法遵(EU AI Act / GDPR)、Fallback、人工 review 流程。
一般聲明
本站提供之資訊僅供參考,不保證其完整性與正確性。使用者應自行判斷資訊之適用性。