C.W.K.
Stream
Lesson 02 of 04 · published

playwright.config.ts — Project, Retry, Worker

~16 min · playwright-setup, config, projects

Level 0테스트 호기심
0 XP0/32 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
"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 원해.

Code

작동하는 config — 필드 여덟, 브라우저 셋, 선택적 모바일·typescript
// playwright.config.ts — a working starting point
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './e2e',
  fullyParallel: true,
  forbidOnly: !!process.env.CI,    // fail CI if .only is committed
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 1 : '50%',
  reporter: process.env.CI ? 'github' : 'html',

  use: {
    baseURL: process.env.BASE_URL ?? 'http://localhost:3000',
    trace: 'on-first-retry',
    screenshot: 'only-on-failure',
    video: 'retain-on-failure',
  },

  projects: [
    { name: 'chromium', use: { ...devices['Desktop Chrome'] } },
    { name: 'firefox',  use: { ...devices['Desktop Firefox'] } },
    { name: 'webkit',   use: { ...devices['Desktop Safari'] } },
    // Optional: mobile viewports
    { name: 'mobile-chrome', use: { ...devices['Pixel 5'] } },
    { name: 'mobile-safari', use: { ...devices['iPhone 13'] } },
  ],

  webServer: {
    command: 'npm run dev',
    url: 'http://localhost:3000',
    reuseExistingServer: !process.env.CI,
    timeout: 120_000,
  },
});
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'

External links

Exercise

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.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.