Skip to content

E2E 테스트 개요

20.5.1. 프레임워크 선택

E2E 테스트 프레임워크로 Playwright를 사용하는 것을 권장합니다.

항목PlaywrightCypress
브라우저 지원Chromium, Firefox, WebKitChromium, Firefox, WebKit (실험적)
실행 속도빠름 (병렬 실행 기본 지원)보통 (병렬 실행 시 유료 플랜 필요)
다중 탭/창지원미지원
iframe 지원네이티브 지원제한적
API 테스트내장 지원플러그인 필요
디버깅 도구Trace Viewer, CodegenCypress Runner
언어 지원TypeScript, JavaScript, Python, Java, .NETTypeScript, JavaScript
  • Playwright는 다중 브라우저 테스트, 병렬 실행, API 테스트를 기본 지원하므로 TQS 기준 권장 프레임워크입니다.
  • Cypress를 이미 사용 중인 프로젝트는 전환을 강제하지 않으나, 신규 프로젝트는 Playwright를 채택합니다.

20.5.2. 핵심 시나리오

E2E 테스트는 사용자의 핵심 업무 흐름을 검증합니다. 아래 시나리오는 필수 테스트 대상입니다.

시나리오검증 항목
로그인/로그아웃정상 로그인, 잘못된 자격 증명 처리, 로그아웃 후 리다이렉트
CRUD 플로우항목 생성, 목록 조회, 상세 조회, 수정, 삭제
에러 처리404 페이지, 서버 오류 시 사용자 피드백, 네트워크 오류 복구
권한 제어미인증 사용자 접근 차단, 권한별 메뉴/기능 노출
폼 제출유효성 검증, 중복 제출 방지, 성공/실패 피드백
typescript
// e2e/auth.spec.ts
import { test, expect } from '@playwright/test'

test.describe('인증 플로우', () => {
  test('정상 로그인 후 대시보드로 이동해야 합니다', async ({ page }) => {
    await page.goto('/login')
    await page.fill('[data-testid="input-email"]', 'user@example.com')
    await page.fill('[data-testid="input-password"]', 'password123')
    await page.click('[data-testid="btn-login"]')

    await expect(page).toHaveURL('/dashboard')
    await expect(page.locator('[data-testid="user-greeting"]')).toBeVisible()
  })

  test('잘못된 비밀번호 시 에러 메시지를 표시해야 합니다', async ({ page }) => {
    await page.goto('/login')
    await page.fill('[data-testid="input-email"]', 'user@example.com')
    await page.fill('[data-testid="input-password"]', 'wrong')
    await page.click('[data-testid="btn-login"]')

    await expect(page.locator('[data-testid="error-message"]')).toBeVisible()
  })
})
  • 모든 핵심 시나리오에 대해 정상 경로와 예외 경로를 모두 테스트합니다.
  • 테스트 시나리오는 사용자 스토리 또는 요구사항 문서와 매핑하여 관리합니다.

20.5.3. 테스트 작성 원칙

사용자 관점 테스트

E2E 테스트는 내부 구현이 아닌 사용자가 보고 상호작용하는 요소를 기준으로 작성합니다.

  • CSS 클래스명이나 컴포넌트 내부 상태에 의존하지 않습니다.
  • data-testid 속성을 사용하여 테스트 대상 요소를 선택합니다.
  • data-testid 네이밍 규칙: {요소유형}-{설명} (예: btn-submit, input-email, list-users)

플레이키 테스트 방지

불안정한(flaky) 테스트는 신뢰도를 저하시키므로 다음 원칙을 준수합니다.

  • 고정된 대기 시간(waitForTimeout) 대신 조건 기반 대기(waitForSelector, expect().toBeVisible())를 사용합니다.
  • 테스트 데이터는 각 테스트에서 독립적으로 생성하고 정리합니다.
  • 외부 API 의존성은 가능한 한 목 서버로 대체합니다.
  • 네트워크 요청 완료를 waitForResponse()로 명시적으로 대기합니다.

20.5.4. CI 연동

CI 환경에서 E2E 테스트를 자동 실행하기 위한 설정입니다.

typescript
// playwright.config.ts
import { defineConfig } from '@playwright/test'

export default defineConfig({
  testDir: './e2e',
  fullyParallel: true,
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 1 : undefined,
  use: {
    baseURL: 'http://localhost:3000',
    trace: 'on-first-retry',
    screenshot: 'only-on-failure',
    video: 'on-first-retry',
  },
  webServer: {
    command: 'yarn dev',
    port: 3000,
    reuseExistingServer: !process.env.CI,
  },
})
설정 항목CI 환경 값설명
retries2실패 시 최대 2회 재시도
workers1안정성을 위해 직렬 실행
screenshotonly-on-failure실패 시 스크린샷 자동 저장
videoon-first-retry첫 번째 재시도 시 비디오 녹화
traceon-first-retry첫 번째 재시도 시 Trace 파일 저장
  • CI 환경에서는 headless 모드로 실행합니다 (Playwright 기본값).
  • 실패 시 생성되는 스크린샷, 비디오, Trace 파일은 CI 아티팩트로 보관합니다.
  • webServer 설정을 통해 테스트 전 개발 서버를 자동으로 시작합니다.
  • 재시도 횟수는 CI에서만 활성화하여 로컬 개발 시에는 즉시 실패를 확인합니다.

TIENIPIA QUALIFIED STANDARD