도입 스토리
"axe DevTools 돌렸더니 오류가 0개예요!" 김개발이 흥분해서 말했습니다.
박멘토가 NVDA를 켜고 페이지를 열었습니다. 잠시 탐색 후 말했습니다.
"폼 필드 레이블이 연결은 됐는데, 내용이 '이름'이 아니라 '이름 (optional)'이에요. 스크린리더는 레이블 전체를 읽으니까 '이름 괄호 optional 괄호 닫음'이라고 읽혀요. 자연스럽지 않아요."
"그건 axe가 못 잡는 거네요?"
"맞아요. 자동화 도구는 코드 구조를 검사해요. 사용자 경험은 직접 써봐야 알아요. 두 방법을 결합해야 해요."
핵심 개념 설명
자동화 vs 수동 테스트 비교
| 항목 | 자동화 도구 | 수동 테스트 |
|---|---|---|
| 발견 가능 오류 | 30~40% | 60~70% 추가 발견 |
| 속도 | 빠름 (수 초) | 느림 (수 분~시간) |
| 주요 탐지 항목 | alt 누락, ARIA 오류, 색상 대비 | 의미 없는 레이블, 불합리한 순서, UX 문제 |
| 도구 | axe, Lighthouse, WAVE | NVDA, VoiceOver, 키보드 탐색 |
axe DevTools 효과적으로 사용하기
기본 사용:
- Chrome DevTools(F12) → axe DevTools 탭 (확장 프로그램 설치 필요)
- "Scan ALL of my page" 클릭
- 심각도 순으로 오류 확인: Critical → Serious → Moderate → Minor
핵심 규칙 카테고리:
- image-alt: 이미지 alt 텍스트
- label: 폼 레이블
- color-contrast: 색상 대비
- aria-*: ARIA 속성 유효성
- keyboard: 키보드 접근성
- duplicate-id: 중복 id
axe를 개발 환경에 통합:
// Jest + axe-core 통합 테스트import { axe, toHaveNoViolations } from 'jest-axe';expect.extend(toHaveNoViolations);test('로그인 폼 접근성', async () => { const { container } = render(<LoginForm />); const results = await axe(container); expect(results).toHaveNoViolations();});
Lighthouse 접근성 감사
Chrome DevTools → Lighthouse → Accessibility 체크 후 실행.
Lighthouse 점수 해석:
90~100: 우수 (배포 준비)
70~89: 양호 (일부 개선 필요)
50~69: 보통 (적극적 개선 필요)
0~49: 불량 (주요 접근성 문제)
Lighthouse는 WCAG 준수가 아닌 Best Practice 기반입니다. 100점이어도 WCAG를 완전히 준수하는 것은 아닙니다.
WAVE — 시각적 접근성 피드백
WAVE(Web Accessibility Evaluation Tool)는 페이지에 직접 아이콘을 overlay합니다.
https://wave.webaim.org/ 또는 Chrome 확장 프로그램
WAVE 아이콘 색상:
- 빨간색: 오류 (반드시 수정)
- 주황색: 경고 (검토 필요)
- 초록색: 구조적 요소 (헤딩, 랜드마크)
- 파란색: ARIA 속성
통합 테스트 전략
효율적인 접근성 테스트 워크플로우:
%% 통합 접근성 테스트 전략
flowchart TB
S1["1단계: 자동화\nCI/CD에 통합"]
S1A["axe-core 단위 테스트"]
S1B["Playwright + axe 통합 테스트"]
S1C["Lighthouse CI"]
S2["2단계: 빠른 수동 검사\nPR마다"]
S2A["키보드 탐색\nTab · Enter · Escape"]
S2B["100% 확대 후 레이아웃 확인"]
S2C["WAVE로 시각적 검토"]
S3["3단계: 심층 스크린리더 테스트\n릴리스마다"]
S3A["NVDA + Chrome\nWindows"]
S3B["VoiceOver + Safari\nmacOS / iOS"]
S3C["TalkBack + Chrome\nAndroid"]
S1 --> S1A
S1 --> S1B
S1 --> S1C
S1 --> S2
S2 --> S2A
S2 --> S2B
S2 --> S2C
S2 --> S3
S3 --> S3A
S3 --> S3B
S3 --> S3C
Playwright로 자동화 접근성 테스트
// playwright.config.jsconst { defineConfig } = require('@playwright/test');module.exports = defineConfig({ use: { baseURL: 'http://localhost:3000', },});
// accessibility.test.jsconst { test, expect } = require('@playwright/test');const AxeBuilder = require('@axe-core/playwright').default;test('홈 페이지 접근성', async ({ page }) => { await page.goto('/'); const results = await new AxeBuilder({ page }) .withTags(['wcag2a', 'wcag2aa']) .analyze(); expect(results.violations).toEqual([]);});test('회원가입 폼 접근성', async ({ page }) => { await page.goto('/signup'); // 키보드 탐색 테스트 await page.keyboard.press('Tab'); const focusedEl = await page.evaluate(() => document.activeElement?.tagName ); expect(focusedEl).toBeTruthy(); // axe 검사 const results = await new AxeBuilder({ page }).analyze(); expect(results.violations).toHaveLength(0);});
단계별 실습
따라하기: 3단계 테스트 흐름 실습
- axe DevTools로 페이지 스캔 — 자동 오류 목록 확인
- Lighthouse로 전체 점수 확인
- 마우스 없이 Tab만으로 회원가입 완료 시도
- NVDA로 같은 폼 탐색 — 레이블이 자연스럽게 읽히는지 확인
변형하기: GitHub Actions에 Lighthouse CI 통합
# .github/workflows/accessibility.ymlname: Accessibility Checkon: [push, pull_request]jobs: accessibility: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Install dependencies run: npm install - name: Build run: npm run build - name: Run Lighthouse CI uses: treosh/lighthouse-ci-action@v10 with: urls: | http://localhost:3000 configPath: '.lighthouserc.json'
// .lighthouserc.json{ "ci": { "assert": { "assertions": { "categories:accessibility": ["error", {"minScore": 0.9}] } } }}
정리와 확인
핵심 내용 요약
- 자동화 도구: axe, Lighthouse, WAVE — 30~40% 오류 발견
- 수동 테스트: 스크린리더, 키보드 — 나머지 60~70% 발견
- 테스트 전략: 자동화(CI) → 빠른 수동(PR) → 심층 스크린리더(릴리스)
- axe-core: Jest, Playwright에 통합하여 회귀 테스트 자동화
- Lighthouse CI: GitHub Actions에 통합하여 접근성 점수 게이팅
확인 문제
문제 1. axe DevTools가 100% 접근성을 보장하지 못하는 이유는?
자동화 도구는 코드 구조의 기술적 오류를 탐지합니다.
레이블이 있지만 의미 없는 내용이거나, 논리적으로 잘못된 읽기 순서,
또는 사용자 경험상 부자연스러운 흐름은 수동 테스트만 발견할 수 있습니다.
문제 2. PR마다 최소 수행해야 할 접근성 테스트는?
1. 키보드만으로 새 기능의 주요 흐름 완료
2. 변경된 영역에 axe 스캔
3. 색상 대비 변경이 있다면 Contrast Checker 확인
PART 08을 마쳤습니다. 다음 PART에서는 접근성 자동화 테스트를 CI/CD 파이프라인에 완전히 통합하는 방법을 다룹니다. 개발 프로세스에 접근성을 내재화하는 전략을 알아봅니다.