e2e-testing은(는) 무엇을 하나요?
Playwright를 사용한 풀스택 Python/React 애플리케이션의 종단 간(E2E) 테스트 패턴. 전체 사용자 워크플로(로그인, CRUD, 내비게이션) 테스트, 중요 경로 회귀 테스트, 또는 교차 브라우저 검증을 작성할 때 사용합니다. 테스트 구조, 페이지 객체 모델, 선택자 전략(data-testid > role > label), 대기 전략, 인증 상태 재사용, 테스트 데이터 관리, CI 통합을 다룹니다. 단위 테스트나 컴포넌트 테스트는 포함하지 않습니다(pytest-patterns 또는 react-testing-patterns 사용).
주요 개념
선택자 우선순위
data-testid속성 사용을 최우선으로 합니다 (예:await page.click('[data-testid="submit-btn"]')).data-testid가 없으면 ARIArole선택자를 사용합니다.- 마지막 수단으로 텍스트
label을 사용하세요.
대기 전략
- 고정된 타임아웃(
page.waitForTimeout())을 피하세요. - 대신 액션이 가능해질 때까지 기다리는
waitForSelector,waitForNavigation,waitForResponse를 사용하세요. - Playwright의 자동 대기 기능(
click()등)을 충분히 활용하세요.
인증 상태 재사용
storageState를 사용하여 로그인 상태를 저장하고 재사용하세요.- 이렇게 하면 모든 테스트에서 반복적으로 로그인할 필요가 없습니다.
- 예제:
// tests/auth.setup.js import { test as setup } from '@playwright/test'; setup('authenticate', async ({ page }) => { await page.goto('/login'); await page.fill('[data-testid="email-input"]', '[email protected]'); await page.fill('[data-testid="password-input"]', 'password'); await page.click('[data-testid="login-btn"]'); await page.waitForURL('/dashboard'); await page.context().storageState({ path: 'e2e-auth.json' }); });
페이지 객체 모델 (POM)
페이지별로 클래스를 생성합니다:
// pages/LoginPage.js
class LoginPage {
constructor(page) {
this.page = page;
this.emailInput = page.locator('[data-testid="email-input"]');
this.passwordInput = page.locator('[data-testid="password-input"]');
this.submitButton = page.locator('[data-testid="login-btn"]');
}
async goto() {
await this.page.goto('/login');
}
async login(email, password) {
await this.emailInput.fill(email);
await this.passwordInput.fill(password);
await this.submitButton.click();
}
}
export default LoginPage;
테스트 데이터 관리
- 테스트에 특화된 데이터는 테스트 파일 내에서 정의하세요.
- 공유 데이터는
testData/디렉토리에 JSON 파일로 저장합니다. - 데이터베이스 시드를 피하기 위해 API 호출을 통해 테스트 데이터를 생성하세요.
CI 통합
GitHub Actions 예제:
# .github/workflows/e2e.yml
name: E2E Tests
on: [push]
jobs:
e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npx playwright install --with-deps
- run: npm run build
- run: npx playwright test
구성
// playwright.config.js
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './tests/e2e',
timeout: 30000,
use: {
baseURL: 'http://localhost:3000',
viewport: { width: 1280, height: 720 },
actionTimeout: 10000,
},
projects: [
{
name: 'chromium',
use: { browserName: 'chromium' },
},
{
name: 'firefox',
use: { browserName: 'firefox' },
},
{
name: 'setup',
testMatch: /.*\.setup\.js/,
},
{
name: 'authenticated',
dependencies: ['setup'],
use: {
storageState: 'e2e-auth.json',
},
},
],
});
고급 패턴
모바일 에뮬레이션
const { devices } = require('@playwright/test');
const iPhone = devices['iPhone 13'];
// 설정에 추가: { use: { ...iPhone } }
시각적 회귀 테스트
- Playwright의
toHaveScreenshot()을 사용하여 시각적 차이를 포착하세요. - 기준 이미지를 커밋하고, 차이가 발생하면 CI에서 테스트를 실패시킵니다.
네트워크 차단
- 외부 요청(분석, 광고 등)을 차단하여 테스트 속도를 높이세요.
await page.route('**/analytics/**', route => route.abort());
비디오 기록
use: {
video: 'on-first-retry',
}
제외 사항
- 단위 테스트:
pytest-patterns스킬 사용 - 컴포넌트 테스트:
react-testing-patterns스킬 사용 - API 전용 테스트: 별도 API 테스트 도구 사용 권장