# 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` 사용
