Files
tasteby/docs/design/343-frontend-test-infra/README.md
joungmin 9ba905aad8 docs(design): #343 RTL/Jest 인프라 + next/image + ARIA Tabs 설계서 (Architect)
next/jest + RTL 도입, 샘플 테스트 3개(Stars + i18n config), remotePatterns,
MyReviewsList Tabs ARIA. 백엔드 JUnit/E2E/CI는 후속.

설계서: docs/design/343-frontend-test-infra/README.md (Approved)
Refs: #343 (Architect)
2026-06-15 16:17:23 +09:00

6.0 KiB

설계서: RTL/Jest 인프라 + next/image + ARIA Tabs (#343)

상태: Approved 작성: [AI] Architect · 최종수정: 2026-06-15 추적성 — Redmine: #343 · 부모: #281 (현행화 frontend-review-memo, 09-Done) · 구현 파일: frontend/package.json, frontend/jest.config.ts (신규), frontend/jest.setup.ts (신규), frontend/next.config.ts, frontend/__tests__/* (신규), frontend/src/components/MyReviewsList.tsx, frontend/src/components/ReviewSection.tsx · 테스트: 본 이슈가 테스트 인프라 자체를 도입

1. 목적 (Why)

본 프로젝트는 지금까지 자동화된 단위 테스트가 0건. 누적된 "후속 테스트" 항목이 12+개(StatsService/CacheService/SearchService/Stars/HangulSimilarity 등)이며, 그동안 분리된 후속 이슈를 처리할 인프라가 없어 모두 보류 상태. 본 이슈에서 Jest + RTL 인프라 도입 + next/image 적용 + ARIA Tabs 보강.

2. 범위 (Scope)

  • 포함
    • Jest 30 + next/jest 자동 설정 + @testing-library/react + @testing-library/jest-dom.
    • jest.config.ts, jest.setup.ts, package.json scripts: test, test:watch.
    • 샘플 테스트 3개 — 가장 안전한 순수 함수/단순 컴포넌트로 인프라 검증:
      • Stars 컴포넌트 렌더 + 별점 표시
      • 기존 HangulSimilarity (#348) — 자모/유사도
      • BotDetector (#337) — 봇 UA 패턴
    • next.config.ts images.remotePatterns에 Google avatar 도메인(lh3.googleusercontent.com) + YouTube thumbnail(i.ytimg.com).
    • ReviewSection/MyReviewsList<img> 일부를 next/image 또는 명시적 eslint-disable로 정리.
    • MyReviewsList 탭에 WAI-ARIA Tabs 패턴(role=tablist/tab/aria-selected/aria-controls).
  • 제외 (후속)
    • 백엔드 JUnit 테스트 인프라 (별도 큰 작업).
    • E2E (Playwright) 도입.
    • CI 통합 (GitHub Actions 또는 OCI DevOps).
    • 모든 컴포넌트 테스트 — 점진적으로 추가.
    • 모든 <img>next/image 전수 교체 — 점진적.

3. 인수조건

  • npm test가 단일 명령으로 동작 (0건 → 샘플 3개 통과).
  • npm run build가 회귀 없이 통과.
  • next.config.tsremotePatterns 설정.
  • ReviewSection의 user_avatar_url <img>next/image 또는 eslint-disable 주석.
  • MyReviewsList 탭이 role="tablist"/role="tab"/aria-selected/aria-controls/tabIndex 설정.

4. 컨텍스트 & 제약

  • Next.js 16.1.6 + Turbopack.
  • next/jest는 SWC/Babel 자동 통합. Turbopack 빌드와는 분리(테스트만 Jest 별도).
  • Pretendard/Geist 폰트는 next/font/local 사용 → 테스트에선 mock 불필요.
  • 패널 분리(#329)로 admin 영역은 단위 테스트 도입 더 쉬워짐.

5. 아키텍처 개요

frontend/
├── package.json
│   └── scripts: test, test:watch
├── jest.config.ts            (next/jest createNextJestConfig 사용)
├── jest.setup.ts             (@testing-library/jest-dom 확장 matchers)
├── __tests__/
│   ├── Stars.test.tsx
│   ├── HangulSimilarity.test.ts   (자체 구현은 backend Java, TS 포팅은 미적용 → 다른 순수 함수로 대체)
│   └── BotDetector.test.ts        (마찬가지 — backend → TS 동등 포팅 불가)
└── (대안) 프론트 측 순수 함수:
    ├── lib/cuisine-icons.ts 의 getPhosphorCuisineIcon
    ├── components/Stars 의 0.5 단위 렌더
    └── i18n/config.ts 의 isLocale/detectBrowserLocale

→ 백엔드 Java 코드는 TS 테스트로 검증 불가. 프론트 측 순수 함수 3개로 대체:

  • Stars 렌더 (RTL component test)
  • i18n/config.ts isLocale (pure)
  • i18n/config.ts detectBrowserLocale (navigator mock)

6. 데이터 모델

__tests__/*.test.{tsx,ts} — Jest 표준 컨벤션.

7. 함수 명세

단위 책임 비고
jest.config.ts createJestConfig(customConfig) + moduleNameMapper @/* next/jest
jest.setup.ts import "@testing-library/jest-dom" 확장 matchers
Stars.test.tsx 별점 0/2.5/5 렌더, aria-label 확인 RTL
i18n/config.test.ts isLocale/detectBrowserLocale navigator mock
MyReviewsList Tabs 패치 tablist/tab/aria-selected role + aria
ReviewSection img → eslint-disable 최소 변경 next/image는 후속

8. 흐름

  1. npm i -D jest jest-environment-jsdom @testing-library/react @testing-library/jest-dom @testing-library/user-event @types/jest.
  2. jest.config.ts + jest.setup.ts 작성.
  3. package.json"test": "jest" + "test:watch": "jest --watch" 추가.
  4. __tests__/에 3개 샘플 테스트.
  5. next.config.tsremotePatterns 추가.
  6. MyReviewsList Tabs ARIA 보강.
  7. ReviewSection<img> 라인에 // eslint-disable-next-line @next/next/no-img-element (next/image 전환은 후속).
  8. npm test 통과 → npm run build 통과.

9. 엣지케이스

  • Turbopack vs Jest: 무관 (테스트는 별도 SWC 컴파일).
  • CSS modules / globals.css import: jest.config.ts의 moduleNameMapper로 \\.(css|scss)$identity-obj-proxy 대신 next/jest가 자동 처리.
  • Next.js Server Components: 본 프로젝트는 모두 "use client" 컴포넌트라 RTL이 통상 동작.

10. 테스트

자기 자신 — npm test가 통과해야 본 이슈 완료.

11. 리스크 & 대안

  • 선택: next/jest + RTL. Next.js 공식 권장.
  • 대안 A: Vitest — 더 빠르지만 Next.js 공식 가이드 부재, 본 프로젝트 규모에서 차이 작음.
  • 대안 B: Playwright Component Testing — 더 무겁고 E2E 통합 안 됨.
  • 트레이드오프: Jest 30 + RTL은 React 19에 호환. 의존성 부담은 dev-only.

12. 미해결 질문

  • CI(테스트 자동 실행) — 본 이슈 범위 밖. OCI DevOps Build Pipeline은 ARM64 미지원 → GitHub Actions 또는 Gitea Actions 후속.
  • 백엔드 JUnit 테스트 인프라 — 별도 큰 이슈.
  • E2E (Playwright) — 별도.