Wiki

← Tất cả bài wiki

playwright.config.ts (File cấu hình trung tâm của test suite)

automationplaywright

playwright.config.ts là file cấu hình gốc điều khiển toàn bộ hành vi của test run: nơi tìm test, timeout, retry, số worker chạy song song, baseURL, các project trình duyệt, reporter và thư mục output. Nắm vững file này = kiểm soát được cách suite chạy trên cả local lẫn CI mà không cần sửa test.

Khái niệm & Bản chất

  • Playwright Test tự đọc playwright.config.ts (hoặc .js, .mjs) ở project root khi chạy npx playwright test; có thể chỉ định file khác bằng --config.
  • Export qua defineConfig() — helper cung cấp type-check và autocomplete; bên trong là plain object nên có thể dùng biểu thức JS tuỳ ý.
  • Gần như mọi flag CLI đều có option tương ứng trong config (--workers, --retries, --project...); flag CLI khi truyền sẽ override giá trị config.
  • Khối use chứa options áp cho TẤT CẢ test (baseURL, trace, screenshot, viewport...); mỗi project có thể khai use riêng để override — đây là cách chạy cùng test trên nhiều browser/device.
  • process.env trong config là cách chuẩn để một file config phục vụ nhiều môi trường: retries: process.env.CI ? 2 : 0, baseURL: process.env.BASE_URL.

Cách hoạt động & API chính

  • Phạm vi test: testDir (thư mục chứa spec), testMatch/testIgnore (glob lọc file).
  • Timeout: timeout (mỗi test, mặc định 30s — gồm cả hook), expect.timeout (mỗi assertion, mặc định 5s), globalTimeout (toàn run). Override per test/file bằng test.setTimeout().
  • Song song: workers (mặc định 50% số CPU), fullyParallel (cho phép song song cả các test trong CÙNG file — đòi hỏi test độc lập dữ liệu).
  • Ổn định CI: retries (số lần chạy lại khi fail), forbidOnly (fail run nếu sót test.only — bắt buộc bật trên CI), maxFailures (dừng sớm khi fail quá nhiều).
  • Artefact: outputDir (nơi chứa trace/screenshot/video, MẶC ĐỊNH BỊ XOÁ SẠCH đầu mỗi run), preserveOutput (giữ artefact của test pass hay không), snapshotDir.
  • webServer: tự khởi động dev server trước khi test và tắt sau khi xong — command, url/port, reuseExistingServer, timeout.

Ví dụ & Cú pháp thực tế

  • Một config hoàn chỉnh, chạy được cả local lẫn CI: ``ts import { defineConfig, devices } from '@playwright/test'; export default defineConfig({ testDir: './tests', timeout: 30_000, // tối đa 30s mỗi test expect: { timeout: 5_000 }, // tối đa 5s mỗi assertion retries: process.env.CI ? 2 : 0, // CI retry 2 lần, local fail ngay workers: process.env.CI ? 4 : undefined,// CI giới hạn 4 worker fullyParallel: true, // song song cả test trong 1 file forbidOnly: !!process.env.CI, // cấm test.only lọt lên CI outputDir: 'test-results', reporter: [['html', { open: 'never' }], ['list']], use: { baseURL: process.env.BASE_URL ?? 'https://dev.hoctest.com', trace: 'on-first-retry', // chỉ ghi trace từ lần retry đầu screenshot: 'only-on-failure', video: 'retain-on-failure', }, projects: [ { name: 'chromium', use: { ...devices['Desktop Chrome'] } }, { name: 'webkit', use: { ...devices['Desktop Safari'] } }, { name: 'mobile', use: { ...devices['iPhone 13'] } }, ], webServer: { command: 'npm run dev', url: 'http://localhost:3000', reuseExistingServer: !process.env.CI, // local tái dùng server đang mở }, }); ``
  • Override option cho một nhóm test mà không sửa config: ``ts import { test, expect } from '@playwright/test'; test.use({ baseURL: 'https://staging.hoctest.com', locale: 'vi-VN' }); test.setTimeout(60_000); // nhóm này được 60s test.describe('checkout', () => { test('thanh toán thành công', async ({ page }) => { await page.goto('/cart'); // đi tới staging vì baseURL đã override }); }); ``
  • Vài flag CLI hay dùng tương ứng với config: ``bash npx playwright test --workers=1 # debug tuần tự npx playwright test --retries=1 --repeat-each=3 # bắt flaky npx playwright test --project=chromium # chỉ chạy 1 browser npx playwright test --grep "@smoke" # lọc theo tag trong title ``

Best practices & Khi nào dùng

  • Một config duy nhất, nhiều môi trường qua env var (BASE_URL, CI) — đừng nhân bản file config cho từng env, sẽ nhanh lệch nhau.
  • trace: 'on-first-retry' là sweet spot: local gần như không tốn dung lượng, còn CI vẫn có đủ bằng chứng để debug test fail/flaky.
  • Bật fullyParallel: true + forbidOnly trên CI để tận dụng CPU và chặn test.only — nhưng trước đó phải đảm bảo test không share data.
  • Giới hạn workers trên CI (4-8) vì runner CI yếu hơn máy dev; local để undefined cho Playwright tự tính.
  • Dùng projects + devices preset để cover browser/mobile thay vì tự khai viewport lung tung.

Gotchas, So sánh & Lưu ý

  • outputDir bị dọn sạch đầu mỗi run — đừng để script khác ghi file cần giữ vào đó; và artefact của test pass chỉ giữ nếu preserveOutput cho phép.
  • timeout tính cả beforeEach/beforeAll vào ngân sách của test đầu tiên — hook nặng có thể làm test "timeout" dù body chưa chạy.
  • fullyParallel làm lộ mọi test phụ thuộc ngầm (ghi cùng user, cùng file): khi bật mà suite bắt đầu flaky thì vấn đề nằm ở test, không phải ở config.
  • test.only trong code sẽ khiến CI fail nếu forbidOnly bật — đó là tính năng cứu người, không phải bug.
  • webServer.reuseExistingServer tiết kiệm vài giây mỗi run ở local, nhưng trên CI phải tắt để luôn chạy đúng code mới build.
  • Option trong use của project merge (shallow) với use global — muốn giữ setting global thì spread cả hai: use: { ...devices['iPhone 13'] } không tự merge baseURL nhưng các key khác vẫn kế thừa.