[2026] Playwright 완벽 가이드 | E2E 테스트·자동화·크로스 브라우저·CI/CD·실전 활용

[2026] Playwright 완벽 가이드 | E2E 테스트·자동화·크로스 브라우저·CI/CD·실전 활용

이 글의 핵심

Playwright로 E2E 테스트를 구현하는 완벽 가이드입니다. 크로스 브라우저 테스트, 자동화, 스크린샷, CI/CD 통합까지 실전 예제로 정리했습니다.

실무 경험 공유: Cypress에서 Playwright로 전환하면서, 테스트 속도가 3배 빨라지고 크로스 브라우저 테스트가 간편해진 경험을 공유합니다.

들어가며: “E2E 테스트가 느려요”

실무 문제 시나리오

시나리오 1: 크로스 브라우저 테스트가 어려워요
Selenium은 복잡합니다. Playwright는 간단합니다. 시나리오 2: 테스트가 느려요
병렬 실행이 필요합니다. Playwright는 기본 지원합니다. 시나리오 3: 디버깅이 어려워요
에러 추적이 힘듭니다. Playwright는 강력한 디버깅 도구를 제공합니다.

1. Playwright란?

핵심 특징

Playwright는 Microsoft가 만든 E2E 테스트 프레임워크입니다. 주요 장점:

  • 크로스 브라우저: Chromium, Firefox, WebKit
  • 빠른 속도: 병렬 실행
  • Auto-wait: 자동 대기
  • 강력한 Selector: CSS, XPath, Text
  • 스크린샷/비디오: 자동 캡처

2. 설치 및 설정

설치

npm init playwright@latest

설정

다음은 typescript를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
  testDir: './tests',
  fullyParallel: true,
  forbidOnly: !!process.env.CI,
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 1 : undefined,
  reporter: 'html',
  use: {
    baseURL: 'http://localhost:3000',
    trace: 'on-first-retry',
    screenshot: 'only-on-failure',
  },
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
    {
      name: 'firefox',
      use: { ...devices['Desktop Firefox'] },
    },
    {
      name: 'webkit',
      use: { ...devices['Desktop Safari'] },
    },
  ],
  webServer: {
    command: 'npm run dev',
    url: 'http://localhost:3000',
    reuseExistingServer: !process.env.CI,
  },
});

3. 기본 테스트

로그인 테스트

다음은 typescript를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 비동기 처리를 통해 효율적으로 작업을 수행합니다, 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

// tests/login.spec.ts
import { test, expect } from '@playwright/test';
test('로그인 성공', async ({ page }) => {
  await page.goto('/login');
  await page.fill('input[name="email"]', 'john@example.com');
  await page.fill('input[name="password"]', 'password123');
  await page.click('button[type="submit"]');
  await expect(page).toHaveURL('/dashboard');
  await expect(page.locator('h1')).toContainText('Dashboard');
});
test('로그인 실패', async ({ page }) => {
  await page.goto('/login');
  await page.fill('input[name="email"]', 'wrong@example.com');
  await page.fill('input[name="password"]', 'wrongpass');
  await page.click('button[type="submit"]');
  await expect(page.locator('.error')).toContainText('Invalid credentials');
});

4. Selector

CSS Selector

await page.click('button.submit');
await page.fill('#email', 'john@example.com');

Text Selector

await page.click('text=로그인');
await page.click('button:has-text("Submit")');

Role Selector

await page.click('role=button[name="Submit"]');
await page.fill('role=textbox[name="Email"]', 'john@example.com');

Chaining

await page.locator('.card').filter({ hasText: 'Premium' }).click();

5. API Mocking

다음은 typescript를 활용한 상세한 구현 코드입니다. 비동기 처리를 통해 효율적으로 작업을 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

test('API 모킹', async ({ page }) => {
  await page.route('**/api/users', (route) => {
    route.fulfill({
      status: 200,
      body: JSON.stringify([
        { id: 1, name: 'John' },
        { id: 2, name: 'Jane' },
      ]),
    });
  });
  await page.goto('/users');
  await expect(page.locator('.user')).toHaveCount(2);
});

6. 스크린샷 & 비디오

스크린샷

아래 코드는 typescript를 사용한 구현 예제입니다. 비동기 처리를 통해 효율적으로 작업을 수행합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

test('스크린샷', async ({ page }) => {
  await page.goto('/');
  await page.screenshot({ path: 'screenshot.png' });
  // 특정 요소
  await page.locator('.card').screenshot({ path: 'card.png' });
});

비디오

아래 코드는 typescript를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

// playwright.config.ts
export default defineConfig({
  use: {
    video: 'on',
  },
});

7. CI/CD 통합

GitHub Actions

다음은 yaml를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# .github/workflows/playwright.yml
name: Playwright Tests
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 20
      - name: Install dependencies
        run: npm ci
      - name: Install Playwright Browsers
        run: npx playwright install --with-deps
      - name: Run Playwright tests
        run: npx playwright test
      - uses: actions/upload-artifact@v3
        if: always()
        with:
          name: playwright-report
          path: playwright-report/

정리 및 체크리스트

핵심 요약

  • Playwright: E2E 테스트 프레임워크
  • 크로스 브라우저: Chromium, Firefox, WebKit
  • Auto-wait: 자동 대기
  • 병렬 실행: 빠른 속도
  • API Mocking: 네트워크 제어
  • CI/CD: GitHub Actions 통합

구현 체크리스트

  • Playwright 설치
  • 설정 파일 작성
  • 기본 테스트 작성
  • Selector 최적화
  • API Mocking 구현
  • 스크린샷 설정
  • CI/CD 통합

같이 보면 좋은 글

  • Cypress E2E 테스트 가이드
  • Jest 테스트 가이드
  • GitHub Actions 가이드

이 글에서 다루는 키워드

Playwright, E2E, Testing, Automation, CI/CD, Browser, QA

자주 묻는 질문 (FAQ)

Q. Cypress와 비교하면 어떤가요?

A. Playwright가 더 빠르고 크로스 브라우저 지원이 좋습니다. Cypress는 DX가 더 좋습니다.

Q. Selenium과 비교하면 어떤가요?

A. Playwright가 훨씬 간단하고 빠릅니다. Selenium은 더 오래됐지만 복잡합니다.

Q. 모바일 테스트도 가능한가요?

A. 네, 모바일 브라우저 에뮬레이션이 가능합니다.

Q. 프로덕션에서 사용해도 되나요?

A. 네, Microsoft, VS Code 등 많은 프로젝트에서 사용합니다.

... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3