Post Detail Page
Storybook - 접근성 테스트 자동화하기(addon, test-runner)
테스트 도입 배경
프로젝트 성능 최적화 기간에 Accessibility(접근성) 개선을 담당하게 되었는데, 개선 과정에서 페이지별로 contrast ratio(명도 대비), label 태그 및 aria-label 누락 등 다양한 접근성 문제가 발견되었다. 한두 개의 문제가 아니라 여러 페이지에서 수정하고 재적용하는 과정을 거치면서 접근성 테스트 자동화의 필요성을 느꼈다.
이를 개선하기 위해 구현된 컴포넌트에 접근성 테스트를 진행하고, 팀 내부에서 이를 공유할 수 있도록 Storybook의 addon
과 test runner
를 활용한 accessibility test
를 도입해 보려고 한다.
addon-a11y
💡
addon-a11y
는 컴포넌트의 접근성 문제를 자동으로 감지하고, 실시간으로 피드백을 제공한다.
1️⃣ Setup
npm install @storybook/addon-a11y --save-dev
2️⃣ .storybook/main.ts
- main.js 파일에
@storybook/addon-a11y
를 추가하여 Storybook에 애드온을 등록한다.
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
import type { StorybookConfig } from '@storybook/your-framework';
const config: StorybookConfig = {
framework: '@storybook/your-framework',
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [
// Other Storybook addons
'@storybook/addon-a11y', //👈 The a11y addon goes here
],
};
export default config;
3️⃣ Storybook
Storybook을 실행한 후, 각 컴포넌트 스토리의 Accessibility
패널에서 접근성 문제를 확인할 수 있다.
접근성 검사를 통과하지 못한 경우, Violations
탭에서 오류 내용과 함께 어떤 부분이 잘못됐는지 안내해 준다.
☹︎ 1 Violations
Serious
섹션을 확인해 보면 ErrorMessage 컴포넌트의 텍스트 컬러인 #dc2626의색상 대비
가4.09
로 4.5:1 요건이 충족되지 않았음을 안내해 준다.(contrast ratio)
test ruuner로 접근성 테스트 자동화하기
1️⃣ Setup
npm install axe-playwright --save-dev
npm install @storybook/test-runner --save-dev
2️⃣ .storybook/test-runner.ts
import type { TestRunnerConfig } from '@storybook/test-runner';
import { injectAxe, checkA11y } from 'axe-playwright';
const config: TestRunnerConfig = {
async preVisit(page) {
await injectAxe(page);
},
async postVisit(page) {
await checkA11y(page, '#storybook-root', {
detailedReport: true,
detailedReportOptions: {
html: true,
},
});
},
};
export default config;
3️⃣ package.json
{
"scripts": {
"test-storybook": "test-storybook"
}
}
4️⃣ 테스트 실행
npm run test-storybook
모든 컴포넌트의 테스트가 약 7.6초에 걸쳐 진행되었음을 볼 수 있다. 실행할 때마다 매번 명령어를 입력하는 대신, 테스트를 자동화하여 프로세스를 효율적으로 개선해 보자.
5️⃣ Set up CI to run tests
💡 CI 환경에서 테스트를 실행하도록 테스트 러너를 구성하는 두 가지 방법이 있다
- Run against deployed Storybooks via Github Actions deployment
- Run against non-deployed Storybooks
두 방법의 차이는 배포된 Storybook
을 대상으로 테스트를 진행하는지, 아니면 배포되지 않은 Storybook
을 대상으로 실행하는지에 따라 다르다.
코드가 배포되기 전에 테스트를 실행하면 배포 이전에 문제를 미리 발견할 수 있고, 코드가 푸시(push) 될 때마다 테스트를 실행하여 빠른 피드백과 함께 수정을 할 수 있다는 장점을 고려하여 두 번째 방법으로 진행하기로 했다.
- Run against non-deployed Storybooks(공식문서 제공)
# .github/workflows/storybook-tests.yml
name: 'Storybook Tests'
on: push
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
- name: Install dependencies
run: yarn
- name: Install Playwright
run: npx playwright install --with-deps
- name: Build Storybook
run: yarn build-storybook --quiet
- name: Serve Storybook and run tests
run: |
npx concurrently -k -s first -n "SB,TEST" -c "magenta,blue" \
"npx http-server storybook-static --port 6006 --silent" \
"npx wait-on tcp:6006 && yarn test-storybook"
테스트가 성공한 후에 chromatic을 배포해야 하므로, chromatic 배포 전에 테스트 작업이 먼저 실행되어야 한다. 이를 위해 아래와 같이 needs 항목을 추가하여 chromatic 작업이 accessiblity-test 작업이 완료된 후에 실행될 수 있도록 수정하여 적용했다.
# .github/workflows/chromatic.yml
name: 'UI TEST'
on: push
jobs:
accessiblity-test:
# ...
chromatic:
needs: accessiblity-test # 테스트 성공 후 실행
name: Run Chromatic
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Cache dependencies
id: cache-node
uses: actions/cache@v4
with:
path: '**/node_modules'
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install dependencies
if: steps.cache-node.outputs.cache-hit != 'true'
run: npm ci
- name: Run Chromatic
uses: chromaui/action@latest
with:
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
위와 같이 Accessibility 테스트가 실패할 경우, Chromatic 배포는 실행되지 않는다.
해당 작업이 의존하는 다른 작업이 완료된 후에만 실행될 수 있도록 보장하기 때문에 Accessibility 테스트가 실패하면 전체 워크플로우가 중단된다.
위와 같이 모든 테스트가 성공하면, Chromatic 배포가 정상적으로 실행되고 완료된다. 이는 코드 변경 사항이 예상대로 작동하며, 모든 접근성 요구사항을 충족함을 보장한다.