Testing & QA Skills — Automation at Scale
Testing & QA 스킬 — 테스트를 무기로 만드는 법
2026년 가장 많이 설치된 Claude Code 스킬은 Playwright E2E다. 테스팅 스킬 스택을 올바르게 구성하면 QA 시간의 80%를 Claude에게 위임할 수 있다.
Overview
테스팅은 Claude Code가 가장 극적인 ROI를 보여주는 영역이다. 이유는 단순하다 — 테스트 작성은 반복 구조가 명확하고 검증 가능한 작업이기 때문이다.
Playwright E2E 스킬이 2026년 설치 수 1위를 차지한 것은 우연이 아니다. E2E 테스트는 작성하기 어렵고, flaky하기 쉽고, CI 설정이 복잡하다 — 정확히 Claude 스킬이 전문성을 발휘하는 지점이다.
테스팅 스킬 스택: Playwright(E2E) + Vitest/Jest(유닛) + RTL(컴포넌트) + MSW(API 모킹) — 이 4개를 갖추면 테스트 코드의 80%를 Claude에게 위임할 수 있다.
- Playwright 스킬로 견고한(flaky하지 않은) E2E 테스트를 작성하는 원칙을 이해한다
- RTL의 올바른 쿼리 우선순위(getByRole > getByText > getByTestId)를 적용할 수 있다
- MSW로 API 모킹을 설정하고 네트워크 계층을 격리하는 방법을 안다
- 테스트 피라미드(유닛:통합:E2E = 70:20:10)를 기준으로 커버리지 전략을 설계한다
Sections
Playwright — 견고한 E2E의 원칙
Playwright 스킬이 가르치는 핵심 원칙:
견고한 로케이터 우선순위: getByRole > getByLabel > getByPlaceholder > getByText > getByTestId. CSS selector나 XPath는 UI 변경에 취약하다.
인증 상태 관리: storageState를 사용해 로그인 상태를 저장하고 재사용. 매 테스트마다 로그인 플로우를 반복하지 않는다.
병렬 실행: worker 수 설정과 test.describe.parallel()로 전체 수트 실행 시간을 극적으로 단축.
React Testing Library — 올바른 테스트 철학
RTL의 핵심 철학: '구현 세부사항이 아니라 사용자 행동을 테스트하라.'
fireEvent보다 userEvent를 쓰는 이유, waitFor의 올바른 사용, findBy 쿼리로 비동기 요소 처리 — RTL 스킬은 이런 미묘한 차이를 Claude가 항상 올바르게 적용하도록 보장한다.
MSW — 네트워크 계층 격리
Mock Service Worker는 서비스 워커 레이어에서 HTTP 요청을 가로채기 때문에 실제 fetch/axios 코드를 수정하지 않아도 된다.
MSW 스킬은 핸들러 설정, setupServer 초기화, 에러 시나리오 모킹, 응답 지연 시뮬레이션 패턴을 Claude가 일관되게 적용하게 한다.
서커스 공중 곡예사가 안전망 없이 연습하지 않는다. 안전망이 있을 때 더 과감한 기술을 시도할 수 있다. 테스트 스위트는 코드베이스의 안전망이다. 스킬로 이 안전망을 빠르게 구축하면, Claude가 더 과감한 리팩토링을 제안하고 실행할 수 있다.
Playwright 스킬이 생성하는 견고한 E2E 테스트 패턴
import { test, expect } from '@playwright/test';
// Playwright 스킬 원칙: 인증 상태 재사용
test.use({ storageState: 'playwright/.auth/user.json' });
test.describe('결제 플로우', () => {
test('장바구니에서 결제 완료까지', async ({ page }) => {
// ✅ getByRole — 가장 견고한 로케이터
await page.goto('/cart');
await page.getByRole('button', { name: '결제하기' }).click();
// ✅ 라벨 기반 — 접근성과 일치
await page.getByLabel('카드 번호').fill('4111111111111111');
await page.getByLabel('유효기간').fill('12/28');
// ✅ 비동기 처리 — waitFor 패턴
await page.getByRole('button', { name: '결제 완료' }).click();
await expect(page.getByRole('heading', {
name: '주문이 완료되었습니다'
})).toBeVisible({ timeout: 10000 });
// ✅ URL 검증
await expect(page).toHaveURL(/\/order\/[a-z0-9-]+/);
});
// ❌ Playwright 스킬이 피하도록 가르치는 패턴:
// await page.click('.checkout-btn'); // CSS selector — 취약
// await page.waitForTimeout(2000); // 하드코딩된 sleep — flaky
}); getByRole로 접근성 기반 로케이터를 사용하고, storageState로 인증을 재사용한다. waitForTimeout 대신 expect().toBeVisible()의 timeout 옵션으로 안정적인 대기를 구현한다.
✅ 시니어가 보는 것
- 접근성 기반 로케이터(getByRole, getByLabel) 사용률
- 인증 상태 재사용으로 테스트 속도 최적화
- flaky 테스트 방지 패턴(waitForTimeout 미사용)
- 테스트 피라미드 비율이 적절한가
Key Takeaways
로케이터 우선순위: Role > Label > Text > TestId
이 순서를 지키는 테스트는 UI가 바뀌어도 살아남는다.
MSW로 네트워크 계층 격리
실제 API에 의존하지 않는 빠르고 신뢰할 수 있는 테스트를 작성한다.
storageState로 인증 재사용
매 테스트 로그인 플로우는 시간 낭비이자 flakiness의 원인이다.