반응형
Notice
Recent Posts
Recent Comments
Link
맞왜틀
Playwright E2E 테스트 추가하기 본문
반응형
🎭 투두 앱에 Playwright E2E 테스트 추가하기
📌 작업 개요
레트로 스타일의 투두 앱에 Playwright를 활용한 E2E(End-to-End) 테스트를 추가했습니다. 접근성(Accessibility)과 테스트 가능성을 함께 개선했습니다.
🎯 주요 작업 내용
2. 접근성(Accessibility) 개선
스크린 리더 사용자와 E2E 테스트를 위해 aria-label 속성을 추가했습니다.
// TodoInput.tsx
<Input
placeholder="오늘 할 일을 입력하세요..."
aria-label="할 일 입력"
/>
<Button onClick={handleSubmit} aria-label="할 일 추가">
ADD
</Button>
// TodoItem.tsx
<Checkbox
onClick={() => onToggleTodo(todo.id)}
aria-label={todo.completed ? '할 일 완료 취소' : '할 일 완료'}
>
{todo.completed ? '✓' : ''}
</Checkbox>
<Button
onClick={() => onRemoveTodo(todo.id)}
aria-label={`${todo.title} 삭제`}
>
DEL
</Button>
💡 핵심 포인트:
삭제 버튼의
삭제 버튼의
aria-label에 투두 제목을 포함시켜 "아침 운동하기 삭제"처럼
어떤 항목을 삭제하는지 명확하게 표현했습니다. 이는 접근성뿐만 아니라
테스트에서 특정 항목을 정확히 선택할 수 있게 해줍니다.
3. Playwright E2E 테스트 작성
총 17개의 테스트 케이스를 작성했습니다.
테스트 카테고리
| 카테고리 | 테스트 수 | 주요 테스트 |
|---|---|---|
| 초기 화면 | 4개 | 제목, 빈 상태, 입력창, 통계 표시 |
| 투두 추가 | 5개 | 버튼 클릭, Enter 키, 입력창 초기화, 여러 개 추가, 빈 문자열 검증 |
| 투두 완료 | 3개 | 완료 처리, 완료 취소, 일부만 완료 |
| 투두 삭제 | 3개 | 삭제, 특정 항목만 삭제, 완료된 항목 삭제 |
| 통계 | 3개 | 추가/완료/삭제 시 통계 업데이트 |
| 통합 시나리오 | 1개 | 추가 → 완료 → 삭제 전체 플로우 |
테스트 코드 구조
test.describe('Todo App', () => {
// 헬퍼 함수로 중복 제거
const getTodoInput = (page: Page) =>
page.getByRole('textbox', { name: '할 일 입력' });
const addTodo = async (page: Page, todoText: string) => {
const input = getTodoInput(page);
await input.fill(todoText);
await page.getByRole('button', { name: '할 일 추가' }).click();
};
test.beforeEach(async ({ page }) => {
await page.goto('/todos');
});
// 테스트는 카테고리별로 그룹화
test.describe('초기 화면', () => { ... });
test.describe('투두 추가', () => { ... });
test.describe('투두 완료', () => { ... });
test.describe('투두 삭제', () => { ... });
test.describe('통계', () => { ... });
test.describe('통합 시나리오', () => { ... });
});
테스트 작성 시 학습한 Best Practices
✅ 헬퍼 함수 활용
중복되는 "투두 추가" 로직을
중복되는 "투두 추가" 로직을
addTodo() 헬퍼 함수로 분리했습니다.
단, 헬퍼 함수에는 검증(assertion)을 넣지 않고 각 테스트에서 명시적으로 검증합니다.
✅ 접근성 기반 선택자 사용
getByRole(), getByLabel() 같은 접근성 기반 선택자를 우선 사용했습니다.
CSS 선택자보다 더 의미론적이고 리팩토링에 강합니다.
✅ 명확한 aria-label
모든 버튼에 고유한
모든 버튼에 고유한
aria-label을 부여해서 테스트에서 정확한 요소를 선택할 수 있게 했습니다.
예: "아침 운동하기 삭제"
4. Playwright 타임아웃 최적화
빠른 피드백을 위해 타임아웃을 대폭 단축했습니다.
// playwright.config.ts
export default defineConfig({
timeout: 10000, // 전체 테스트: 10초 (기본 30초)
use: {
actionTimeout: 3000, // 클릭, fill 등: 3초
navigationTimeout: 5000, // 페이지 이동: 5초
},
expect: {
timeout: 3000, // assertion: 3초
},
});
⚡ 효과: 테스트 실패 시 30초 대기 → 3초 만에 빠르게 실패하여 개발 속도가 10배 향상되었습니다.
📦 커밋 내역
2293f49
config: Playwright 타임아웃 3초로 최적화
5e120b1
test: 투두 앱 Playwright e2e 테스트 추가
96fdeca
feat: 투두 컴포넌트에 aria-label 접근성 속성 추가
b08ac20
refactor: 투두 앱 포켓몬 테마 제거 및 일반 텍스트로 변경
💡 배운 점
1. Playwright 선택자 전략
getByRole('button', { name: '할 일 추가' })- 접근성 기반, 가장 권장getByLabel('할 일 입력')- label 요소와 연결된 input 선택getByPlaceholder('...')- placeholder로 선택 (보조적으로 사용)getByText('아침 운동하기')- 텍스트로 선택 (간단할 때 유용)
2. 테스트 구조화
- 헬퍼 함수: Setup 용도로만 사용 (assertion 없이)
- 테스트: 명시적인 검증 포함 필수
- 그룹화:
test.describe()로 카테고리별 정리
3. 접근성과 테스트의 시너지
- 접근성을 위해 추가한
aria-label이 테스트 작성을 훨씬 쉽게 만듦 - 고유한 레이블은 스크린 리더와 자동화 테스트 모두에게 유용
- 좋은 접근성 = 좋은 테스트 가능성
🚀 다음 단계
CI/CD 통합
GitHub Actions에 Playwright 테스트를 추가하여 PR 생성 시 자동으로 테스트가 실행되도록 설정할 예정입니다.
GitHub Actions에 Playwright 테스트를 추가하여 PR 생성 시 자동으로 테스트가 실행되도록 설정할 예정입니다.
// .github/workflows/ci.yml (예정)
jobs:
e2e-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: npm ci
- run: npx playwright install --with-deps
- run: npx nx e2e web-e2e
📊 테스트 실행 방법
# 전체 테스트 실행
npx nx e2e web-e2e
# UI 모드로 실행 (디버깅)
npx nx e2e web-e2e --ui
# 특정 브라우저만 실행
npx nx e2e web-e2e --project=chromium
🎉 결론
처음 Playwright를 도입하면서 E2E 테스트 작성 방법과 접근성의 중요성을 함께 배울 수 있었습니다.
특히 aria-label을 제대로 활용하면 접근성과 테스트 가능성을 동시에 향상시킬 수 있다는 점이
가장 큰 수확이었습니다.
타임아웃을 3초로 줄여서 테스트 실패 시 빠르게 피드백을 받을 수 있게 된 것도 개발 경험을 크게 개선시켰습니다. 앞으로는 CI/CD에 통합해서 더욱 안정적인 개발 프로세스를 구축할 예정입니다.
반응형
'개발 일지 > 회사 기술 스택' 카테고리의 다른 글
| React Native + Next.js WebView: 네이티브와 웹을 자유롭게 오가는 법 (0) | 2025.11.02 |
|---|---|
| 💎 Expo Router Stack Navigator 실전 패턴과 꿀팁 (0) | 2025.11.01 |
| Expo Router 25.10 패치 노트 - 모바일 네비게이션의 새로운 시대 (0) | 2025.10.26 |
| React Native 웹뷰로 웹앱을 네이티브 앱처럼 만들기 (feat. 삽질 경험담) (1) | 2025.10.22 |
| Nx 모노레포에서 React Native 앱 만들다가 3시간 날린 썰 (feat. 해결법) (0) | 2025.10.20 |