playwright-best-practices은(는) 무엇을 하나요?
Playwright 테스트 작성, 불안정한(flaky) 테스트 수정, 실패 디버깅, Page Object Model 구현, CI/CD 구성, 성능 최적화, API 모킹, 인증/OAuth 처리, 접근성 테스트(axe-core), 파일 업로드/다운로드, 날짜/시간 모킹, WebSocket, 지리적 위치, 권한, 다중 탭/팝업 흐름, 모바일/반응형 레이아웃, 터치 제스처, GraphQL, 오류 처리, 오프라인 모드, 다중 사용자 협업, 서드파티 서비스(결제, 이메일 인증), 콘솔 오류 모니터링, 전역 설정/해제, 테스트 어노테이션(skip, fixme, slow), 테스트 태그(@smoke, @fast, @critical, --grep을 사용한 필터링), 프로젝트 종속성, 보안 테스트(XSS, CSRF, 인증), 성능 예산(Web Vitals, Lighthouse), iframe, 컴포넌트 테스트, canvas/WebGL, 서비스 워커/PWA, 테스트 커버리지, i18n/지역화, Electron 앱 또는 브라우저 확장 프로그램 테스트 시 사용하십시오. E2E, 컴포넌트, API, 시각적, 접근성, 보안, Electron 및 확장 프로그램 테스트를 모두 다룹니다.
개요
이 스킬은 Playwright를 활용한 테스트 자동화의 모범 사례를 제공합니다. 각 주제는 플랫폼 핵심 개념과 일반적인 문제 해결 방법을 포함합니다.
AI 모델 지침
Playwright 관련 질문에 답변할 때:
- 공식 문서 우선: 플레이와 관련된 조언은 항상 playwright.dev/docs를 참조하십시오. 일관성을 위해 문서의 용어와 패턴을 사용하십시오.
- Playwright 네이티브 사용:
puppeteer라이브러리 대신 Playwright의page.waitForSelector()또는page.waitForResponse()와 같은 내장 메커니즘을 우선 사용하십시오. - 비동기/대기 패턴: 모든 Playwright 메서드가 프라미스를 반환하므로
await을 올바르게 사용하십시오. 필요하지 않은page.waitFor(timeout)사용은 피하십시오. - 구체적인 예제 제시: 권장 사항에 항상 구체적인 코드 예제를 포함시켜 수동과 AI 모두에게 명확한 참조를 제공하십시오.
- Flakiness 최소화: 불안정성을 줄일 수 있는 방법(예: 고정 대기 시간 대신 web-first assertion 사용)을 제안하십시오.
- 비결정적 해결 지양: "가끔 작동함" 또는 "대부분 통과함" 식의 해결책을 제시하지 마십시오. 예측 가능하고 안정적인 테스트가 목표여야 합니다.
- 근본 원인 분석: 오류 메시지에서 실제 문제를 식별하도록 안내하십시오. 단순히
page.waitForTimeout(2000)을 추가하는 등 증상을 억제하지 마십시오. - Playwright 생태계:
@playwright/test,playwright-core, 브라우저별 실행 파일의 차이점을 이해하고 있어야 합니다.
구성
- 타임아웃: 테스트가 예상보다 오래 걸리는 CI 환경에서는
timeout: 60000(60초)과 같은 전역 타임아웃을 구성하는 것을 고려하십시오. - 재시도:
retries: 2를 설정하면 불안정한 테스트를 수정하는 동안 파이프라인 안정성을 높이는 데 도움이 될 수 있습니다. - 동시성:
workers: 4와 같은 값을 설정하면 많은 테스트가 있는 제품군에서 속도를 높일 수 있습니다. - 테스트 필터링:
--grep으로 태그를 사용하여 특정 테스트 그룹을 실행하십시오. 예:npx playwright test --grep @smoke
일반적인 문제
| 문제 | 증상 | 일반적인 해결책 |
|---|---|---|
| Flakiness | 재시도 없이 무작위로 실패함 | Web-first assertion 사용, 대기 시간 추가 |
| 경쟁 조건 | 특정 순서에서만 작동함 | 타이머 대신 waitForSelector 사용 |
| 시간 초과 | 작업이 완료될 때까지 기다리지 않음 | 적절한 타임아웃 증가, 액션 가능한 상태 대기 |
| 복잡한 선택자 | 오래되거나 동적으로 변경되는 요소 | data-testid 또는 role 기반 선택자 사용 |
| 인증 문제 | 설정이 부족함 | 전역 설정에서 재사용 가능한 인증 상태 구성 |
심층 주제
1. 불안정한(Flaky) 테스트
- 증상: 무작위로 실패하며 특정 변경 사항 없이 재시도 시 통과합니다.
- 근본 원인: 일반적으로 경쟁 조건, 부적절한 대기 전략 또는 비결정적 동작입니다.
- 해결 방법:
page.waitForSelector,page.waitForResponse등 web-first assertion을 사용하십시오. 고정page.waitFor(timeout)사용을 피하십시오.
코드 예제:
// 불량 (고정 대기)
await page.waitForTimeout(2000);
const button = await page.locator('.save-btn');
// 양호 (조건 대기)
await page.locator('.save-btn').waitFor({ state: 'visible' });
await expect(page.locator('.save-btn')).toBeEnabled();
2. API 모킹
- 개념: 네트워크 응답을 가로채 테스트 격리를 보장합니다.
- 용도: 외부 API에 의존하는 시나리오, 오류 처리, 에지 케이스 테스트.
- 권장 패턴:
page.route()를 사용하여 특정 URL 패턴을 가로채십시오.
코드 예제:
await page.route('**/api/user', route => {
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ id: 1, name: 'Mocked User' }),
});
});
3. 인증 헬퍼
- 전략:
playwright/.auth에 인증 상태를 저장하고 전역 설정에서 재사용하십시오. - 이점: 각 테스트에서 반복적인 로그인을 방지하고 시간과 리소스를 절약합니다.
코드 예제:
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
storageState: 'playwright/.auth/user.json',
},
});
4. 시각적 회귀 테스트
- 도구: Playwright에는
expect(page).toHaveScreenshot()을 통한 내장 시각적 비교가 포함되어 있습니다. - 최상의 방법: 예측 가능한 스냅샷을 위해 뷰포트를 고정하고 동적 콘텐츠(예: 날짜/시간)를 마스킹하십시오.
- 처리:
maxDiffPixelRatio임계값으로 미미한 차이를 허용하십시오.
코드 예제:
test('홈페이지 스크린샷', async ({ page }) => {
await page.goto('https://example.com');
await expect(page).toHaveScreenshot({ maxDiffPixelRatio: 0.02 });
});
5. 파일 업로드/다운로드
- 업로드: 파일 입력이 숨겨져 있어도 상호 작용할 수 있는
page.setInputFiles를 사용하십시오. - 다운로드:
page.waitForEvent('download')를 사용하여 다운로드가 완료될 때까지 기다립니다. 경로를 확인하고 내용을 테스트하십시오.
코드 예제:
const [download] = await Promise.all([
page.waitForEvent('download'),
page.locator('button.download').click(),
]);
const filePath = await download.path();
console.log('다운로드한 파일 경로:', filePath);
6. 접근성 테스트 (axe-core)
- 도구: Playwright 테스트 내에서
@axe-core/playwright를 사용하십시오. - 방법: 페이지가 완전히 렌더링된 후에 접근성 검사를 실행하십시오. 특정 규칙이나 태그(예:
wcag2aa)를 선택할 수 있습니다.
코드 예제:
import { injectAxe, checkA11y } from 'axe-playwright';
test('접근성 위반 사항이 없어야 함', async ({ page }) => {
await page.goto('https://example.com');
await injectAxe(page);
await checkA11y(page);
});
7. 오류 처리 및 디버깅
- 전략: 실패에 대한 컨텍스트를 제공하기 위해 테스트 실패 시 스크린샷 및 트레이스 뷰어를 캡처하십시오.
- 구성:
playwright.config.ts에서screenshot: 'only-on-failure'및trace: 'retain-on-failure'를 활성화하십시오.
구성 예제:
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
screenshot: 'only-on-failure',
trace: 'retain-on-failure',
},
});
8. 테스트 태그 및 어노테이션
- 태그:
@smoke,@fast,@critical과 같은 태그를 사용하여 테스트를 분류하십시오.--grep으로 필터링하십시오:npx playwright test --grep @smoke. - 어노테이션:
test.skip(),test.fixme(),test.slow()를 사용하여 테스트 실행을 제어하십시오.
코드 예제:
test.skip('건너뛸 테스트', async ({ page }) => { /* ... */ });
test.fixme('수정해야 할 테스트', async ({ page }) => { /* ... */ });
test.slow('느린 테스트', async ({ page }) => { /* ... */ });
9. 프로젝트 종속성
- 용도:
testProject.dependencies를 사용하여 순서를 적용하십시오(예: 먼저 로그인 테스트를 실행한 다음 다른 테스트 실행).teardown프로젝트를 사용하여 리소스를 정리하십시오.
구성 예제:
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
projects: [
{
name: 'setup',
testMatch: '**/*.setup.ts',
},
{
name: 'e2e',
dependencies: ['setup'],
},
{
name: 'teardown',
dependencies: ['e2e'],
},
],
});
10. 성능 예산
- 개념: Web Vitals, Lighthouse 점수에 대한 임계값을 정의하십시오. Playwright는 성능 메트릭을 감사할 수 있습니다.
- 확인:
page.evaluate()를 사용하고 Lighthouse 점수를 프로그래밍 방식으로 확인하십시오.
코드 예제:
test('성능 예산 충족', async ({ page }) => {
await page.goto('https://example.com');
const metrics = await page.evaluate(() => JSON.stringify(window.performance));
// 메트릭을 확인하는 어설션
});
도움말 및 문제 해결
- 디버깅이 필요한가요? Chrome DevTools를 열거나 Playwright Trace Viewer를 사용하여 테스트 단계를 검사하십시오.
- CLI 도움말:
npx playwright --help를 사용하여 사용 가능한 모든 명령과 옵션을 확인하십시오. - 현재 프로젝트 구성 확인: Playwright 설정을 보려면
npx playwright test --list를 실행하십시오. - 브라우저 설치:
npx playwright install을 사용하여 필요한 브라우저 바이너리가 설치되었는지 확인하십시오. - 도커에서 테스트: 공식 Playwright Docker 이미지를 사용하여 일관된 브라우저 지원으로 CI에서 안정적으로 실행하십시오.
더 많은 예제와 심층 문서는 Playwright 문서를 참조하십시오.