- CLAUDE.md: React/TypeScript/Vite 프로젝트 가이드 - .claude/settings.json: npm/Node.js 빌드 도구 권한 설정 - .claude/rules/: TypeScript/React 코드 스타일, 네이밍, 테스트 규칙 - .githooks/pre-commit: TypeScript 타입체크 + ESLint 검증 - .npmrc: Nexus npm 프록시 레지스트리 - .prettierrc: 코드 포맷팅 설정 - .node-version: Node.js 버전 고정
65 lines
2.2 KiB
Markdown
65 lines
2.2 KiB
Markdown
# TypeScript/React 테스트 규칙
|
|
|
|
## 테스트 프레임워크
|
|
- Vitest (Vite 프로젝트) 또는 Jest
|
|
- React Testing Library (컴포넌트 테스트)
|
|
- MSW (Mock Service Worker, API 모킹)
|
|
|
|
## 테스트 구조
|
|
|
|
### 단위 테스트
|
|
- 유틸리티 함수, 커스텀 훅 테스트
|
|
- 외부 의존성 없이 순수 로직 검증
|
|
|
|
```typescript
|
|
describe('formatDate', () => {
|
|
it('날짜를 YYYY-MM-DD 형식으로 변환한다', () => {
|
|
const result = formatDate(new Date('2026-02-14'));
|
|
expect(result).toBe('2026-02-14');
|
|
});
|
|
|
|
it('유효하지 않은 날짜는 빈 문자열을 반환한다', () => {
|
|
const result = formatDate(new Date('invalid'));
|
|
expect(result).toBe('');
|
|
});
|
|
});
|
|
```
|
|
|
|
### 컴포넌트 테스트
|
|
- React Testing Library 사용
|
|
- 사용자 관점에서 테스트 (구현 세부사항이 아닌 동작 테스트)
|
|
- `getByRole`, `getByText` 등 접근성 기반 쿼리 우선
|
|
|
|
```tsx
|
|
describe('UserCard', () => {
|
|
it('사용자 이름과 이메일을 표시한다', () => {
|
|
render(<UserCard name="홍길동" email="hong@test.com" />);
|
|
expect(screen.getByText('홍길동')).toBeInTheDocument();
|
|
expect(screen.getByText('hong@test.com')).toBeInTheDocument();
|
|
});
|
|
|
|
it('편집 버튼 클릭 시 onEdit 콜백을 호출한다', async () => {
|
|
const onEdit = vi.fn();
|
|
render(<UserCard name="홍길동" email="hong@test.com" onEdit={onEdit} />);
|
|
await userEvent.click(screen.getByRole('button', { name: '편집' }));
|
|
expect(onEdit).toHaveBeenCalledOnce();
|
|
});
|
|
});
|
|
```
|
|
|
|
### 테스트 패턴
|
|
- **Arrange-Act-Assert** 구조
|
|
- 테스트 설명은 한국어로 작성 (`it('사용자 이름을 표시한다')`)
|
|
- 하나의 테스트에 하나의 검증
|
|
|
|
## 테스트 커버리지
|
|
- 새로 작성하는 유틸리티 함수: 테스트 필수
|
|
- 컴포넌트: 주요 상호작용 테스트 권장
|
|
- API 호출: MSW로 모킹하여 에러/성공 시나리오 테스트
|
|
|
|
## 금지 사항
|
|
- 구현 세부사항 테스트 금지 (state 값 직접 확인 등)
|
|
- `getByTestId` 남용 금지 (접근성 쿼리 우선)
|
|
- 스냅샷 테스트 남용 금지 (변경에 취약)
|
|
- `setTimeout`으로 비동기 대기 금지 → `waitFor`, `findBy` 사용
|