"Config 는 '테스트 하나' 가 무슨 뜻인지 결정하는 곳 — 브라우저 하나? 셋? auth 있게? 모바일 폭에서?"
값어치하는 여덟 필드
playwright.config.ts 는 커질 수 있지만, 작동하는 config 는 몇 필드에 의지:
testDir — 테스트가 사는 곳 (default ./tests; init 가 보통 ./e2e 설정).
use.baseURL — 모든 page.goto('/path') 가 이거에 대해 resolve. dev 에선 http://localhost:3000; CI 에선 env 통해 오버라이드.
use.trace — trace 캡처 시점. 'on-first-retry' 가 sweet spot: 성공엔 오버헤드 없음, 실패엔 풀 포렌식.
retries — 실패한 테스트를 실패로 마크하기 전 몇 번 재시도. 로컬은 0, CI 는 2 (단일 flake 재시도가 대부분 네트워크 jitter 잡아).
workers — 병렬성. 로컬은 CPU 코어의 '50%' 가 좋은 default; CI 컨테이너는 OOM 피하려 더 낮게.
reporter — 출력 형식. dev 는 'html' (브라우저 리포트 열어줌); CI 는 'list' 나 'github'.
webServer — Playwright 가 테스트 전에 dev 서버 시작하고 후에 tear down 가능. Fresh 빌드에 대해 테스트 돌게 보장하는 데 critical.
projects — multi-browser / multi-config 차원.
Project 가 킬러 feature
'Project' 는 명명된 config 변형. { name: 'chromium', use: { ...devices['Desktop Chrome'] } } 는 "내 테스트를 desktop Chrome 에서 돌려." 항목 세 개 더 추가하면 chromium + firefox + webkit, 다 병렬로 돌고, 브라우저별 결과 리포트.
Project 는 viewport / 모바일 / 인증된 state 도 처리. 흔한 setup:
setup project — auth state 를 파일에 저장하는 단일 로그인 spec 돌림.
chromium project — setup 에 의존, 저장된 state 사용, 메인 suite 돌림.
mobile-chrome project — 같은 suite, 모바일 viewport.
firefox, webkit — 크로스 브라우저 패스.
Project 는 너의 필요에 맞춰 확장, 거꾸로 아냐. 첫날: project 하나, default Chromium, auth 없음. 필요한 날 project 추가 — 모바일 테스트, 크로스 브라우저 sweep, 인증된 흐름. '혹시나' 로 project 다섯 개 사전 설정하지 마 — 매 project 가 CI 시간 세 배.
webServer 필드 — 잊지 마
테스트는 통신할 뭔가가 필요. webServer 필드가 Playwright 에게 테스트 전 dev 서버 시작하는 법과 기다릴 URL 말해줘. 없으면 매 테스트 run 전에 수동으로 서버 시작 기억해야 해 — 로컬은 괜찮지만 CI 에선 치명적.
테스트별 오버라이드
Config 가 default 설정. 개별 테스트나 테스트 파일이 test.use({...}) 로 대부분 필드 오버라이드. 다른 viewport, 다른 storage state, 다른 user-agent 필요한 테스트에 유용. 첫날부터 손 뻗지 마 — 대부분 테스트는 config default 원해.
Auth 인식 project setup (전체 패턴은 track 8 에서)·typescript
// Auth project pattern — log in once, reuse the state in every test
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
projects: [
// 1. Runs first, no dependency. Saves auth state to a file.
{
name: 'setup',
testMatch: /global\.setup\.ts/,
},
// 2. Depends on setup. Loads the saved state automatically.
{
name: 'chromium',
dependencies: ['setup'],
use: {
...devices['Desktop Chrome'],
storageState: 'playwright/.auth/user.json',
},
},
// 3. A second project that DOESN'T log in (e.g., public pages).
{
name: 'chromium-public',
testMatch: /\.public\.spec\.ts/,
use: { ...devices['Desktop Chrome'] },
// No storageState — no auth state.
},
],
});
테스트/파일별 오버라이드·typescript
// Per-test override — when one test needs different defaults
import { test, expect } from '@playwright/test';
// Override the viewport for this entire file
test.use({ viewport: { width: 320, height: 568 } });
test('mobile menu opens', async ({ page }) => {
await page.goto('/');
// Mobile-only assertions...
});
// Or override just one test inside a describe
test.describe('admin features', () => {
test.use({ storageState: 'playwright/.auth/admin.json' });
test('admin can delete posts', async ({ page }) => {
// Logged in as admin via the override
});
});
CLI — project / 파일 / 테스트 이름으로 필터·bash
# Run all projects (default)
npx playwright test
# Run only one project
npx playwright test --project=chromium
# Run multiple
npx playwright test --project=chromium --project=webkit
# Run a single test file across all projects
npx playwright test e2e/login.spec.ts
# Combine — one file, one project
npx playwright test e2e/login.spec.ts --project=chromium
# Headed (see the browser) — great for local debugging
npx playwright test --headed --project=chromium
# Run only tests whose name matches a pattern
npx playwright test -g 'admin can delete'
init 의 config 가져와서 devices['Pixel 5'] 쓰는 mobile-chrome project 추가. npx playwright test --project=mobile-chrome 돌려서 예제 테스트가 모바일 폭에서 도는 거 봐. 그 다음 실제 dev 서버용 webServer 블록 추가. 수동으로 서버 시작 안 하고 다시 돌려 — Playwright 가 시작해줘야. 테스트가 https://playwright.dev/ 로 하드코드돼 있으면 / 로 바꾸고 baseURL 에 의존.
Hint
webServer 가 'timed out waiting for URL' 로 실패하면 dev 서버가 준비되는 데 60초 넘게 걸리거나 지정한 url 이 200 응답 안 하는 거. timeout: 180_000 으로 올리고 URL 을 curl 로 더블 체크.
Progress
Progress is local-only — sign in to sync across devices.