DOCS/book/300_architecture/315_테스트_원칙.md
Claude-51124 d79ba256de docs: ideas·시나리오·UX 테스트 원칙 보강
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-04 10:43:56 +09:00

7.7 KiB

테스트 원칙

작성일: 2025-01-03 수정일: 2026-02-04 (UX 검증 원칙 추가) 참고: 311_백엔드_구조_원칙.md, 312_문서_작성_원칙.md


1. 핵심 원칙

TDD 원칙

테스트는 TDD로 진행한다.

  • Red: 테스트 먼저 작성 (기대 행동을 테스트에 명시)
  • Green: 최소 구현으로 테스트 통과
  • Refactor: 리팩터링 후 테스트 재실행

DecisionEngine, intent, 캘린더 로직 등은 항상 테스트에서 기대 행동을 확정한 뒤 수정한다.

UX 검증 원칙

  • 사용자가 실제로 보는 문구·행동만 검증한다 (예: 응답 문장, 버튼 노출 여부)
  • 내부 안내/제약 설명(“직접 언급 금지” 같은 시스템 지시문)은 금지어 검증 대상이 아님
  • UX 규칙(감정 직접 표현 금지 등)은 사용자 시나리오 테스트로 재현한다

테스트 코드 재작성 비효율 방지

목표: 테스트 코드를 매번 재작성하지 않고 재사용 가능하게 관리

원칙 (상세: 섹션 2-5 참조):

  • 재사용성 우선: 공통 테스트 로직은 fixtures/유틸리티로 추출 (섹션 3)
  • 자동화 필수: pytest 기반 자동 테스트만 유지 (섹션 6)
  • 중복 제거: 동일 기능 테스트는 하나로 통합 (섹션 4)

2. 테스트 파일 분류 및 위치

유형 위치 관리 방식
pytest 자동 테스트 tests/test_*.py 버전 관리, 지속 유지 (.gitignore 제외 금지)
실험/관찰 스크립트 scripts/ (임시) 작업 완료 즉시 삭제
공통 fixtures tests/conftest.py 재사용 우선
테스트 데이터 tests/data/, tests/fixtures/ 공유 가능하도록 구조화

금지 사항

금지 이유 참조
tests/에 실험 스크립트 저장 자동 테스트와 혼재, 정리 어려움 섹션 5, 6
수동 실행 스크립트 장기 보관 재작성 비효율 유발 섹션 5
중복 테스트 파일 유지 유지보수 비용 증가 섹션 4
.gitignoretests/test_*.py 제외 버전 관리 필요 섹션 2

3. 테스트 코드 재사용성

공통 로직 추출

권장: pytest fixtures 사용

# tests/conftest.py
@pytest.fixture
def mock_llm_service():
    """LLM 서비스 모킹 - 모든 테스트에서 재사용"""
    with patch('app.services.llm.llm_service.LLMService') as mock:
        yield mock

# tests/test_intent.py
def test_intent_classification(mock_llm_service):
    # mock_llm_service 자동 주입
    ...

금지: 각 테스트 파일에서 동일한 모킹 코드 반복 작성

테스트 데이터 관리

권장: 공통 데이터 파일 사용

  • tests/data/intent_eval_samples.json: 의도 분류 샘플 데이터
  • tests/fixtures/: 재사용 가능한 모킹 객체

금지: 테스트 파일 내 하드코딩된 데이터 반복


4. 중복 테스트 통합

통합 대상

중복 패턴 처리 방법
test_overlap_cases.py + test_overlap_tdd.py 하나로 통합 (최종 버전 유지)
TDD 단계별 테스트 파일 최종 버전만 유지
test_*_vs_*.py 비교 테스트 troubleshooting 기록 후 삭제

유지 기준 (상세: 섹션 6 참조)

  • 유지: pytest로 재현 가능한 자동 테스트
  • 삭제: 임시 실험, 비교 테스트, refactoring 테스트 (섹션 5)

5. 임시 테스트 정리

즉시 삭제 대상

대상 패턴 처리 시점
리팩토링 테스트 test_*_refactoring.py 작업 완료 후
비교 실험 test_*_vs_*.py troubleshooting 기록 후
관찰용 스크립트 "서비스 코드 수정 없이 관찰" 주석 작업 완료 즉시
수동 실행 스크립트 python3 직접 실행, pytest 미적용 작업 완료 즉시 (섹션 6)
실험 결과 파일 .md, .json 결과 파일 troubleshooting 문서화 후

정리 프로세스

  1. 문제 해결 → troubleshooting 문서 작성
  2. 핵심 교훈 기록
  3. 임시 테스트 파일 삭제

6. pytest 자동 테스트 기준

필수 요구사항

pytest 자동 테스트 확인 방법:

  • import pytest 또는 @pytest.mark.* 데코레이터 사용
  • pytest tests/test_*.py 명령으로 실행 가능
  • if __name__ == "__main__" 직접 실행 코드 없어야 함

금지 사항:

  • python3 tests/test_*.py 방식의 수동 실행 스크립트
  • "pytest 없이 직접 실행" 주석이 있는 파일
  • pytest import 없이 def test_*() 함수만 있는 파일 (pytest 미적용)

테스트 파일 검증

추가 전 확인:

# pytest로 실행 가능한지 확인
pytest tests/test_*.py -v

# pytest import 여부 확인
grep -l "import pytest\|@pytest" tests/test_*.py

컨테이너 테스트 파일 반영

배경: tests 디렉토리는 볼륨 마운트가 아님 (Dockerfile에서 COPY ./tests /code/tests로 빌드 시만 복사)

새 테스트 파일 추가 시:

# 방법 1: docker cp (빠름, 재빌드 불필요)
docker cp tests/test_new_feature.py rb8001:/code/tests/

# 방법 2: 컨테이너 재빌드 (확실함)
docker compose down && docker compose up -d --build

주의: 호스트에서 테스트 파일 수정 후 컨테이너에 반영 안 되는 문제 주의


7. 테스트 네이밍 및 구조

파일명 규칙

패턴 용도 예시
test_{기능}.py 기능 단위 테스트 test_intent_classification.py
test_{엔드포인트}_endpoint.py API 엔드포인트 테스트 test_diary_endpoint.py
e2e/test_{워크플로우}.py E2E 테스트 e2e/test_coldmail_full_flow.py

금지 네이밍

  • test_*_refactoring.py (작업 완료 후 삭제)
  • test_*_vs_*.py (비교 실험, 결과 기록 후 삭제)
  • e2e_*.py (tests 루트에, e2e/ 폴더로 이동)
  • 중복된 e2e 테스트: test_e2e_*.pytest_*_e2e.py (하나로 통합)

8. 체크리스트

테스트 작성 전

  • TDD 순서 준수 (Red → Green → Refactor)
  • 동일한 테스트 로직이 이미 존재하는가? (섹션 3 재사용성 확인)
  • 공통 모킹/데이터가 있다면 conftest.py에 추가할 수 있는가? (섹션 3)
  • pytest 자동 테스트인가? (섹션 6 기준 확인)

테스트 파일 추가 전

  • 중복 테스트 파일이 있는가? (섹션 4 통합 가능한지 확인)
  • 임시 실험 파일인가? (섹션 5 삭제 계획 수립)
  • 네이밍 규칙 준수 (섹션 7)
  • .gitignore에 제외 규칙이 있는가? (섹션 2 - 테스트 파일은 버전 관리 필수)

정리 시점 (섹션 5, 9 참조)

  • 리팩토링/비교 테스트 → troubleshooting 기록 후 삭제
  • 실험/수동 스크립트 → 작업 완료 즉시 삭제
  • 중복 테스트 → 통합 또는 삭제

9. 정리 프로세스 예시

실제 정리 사례 (2025-01-03)

삭제된 파일:

  1. test_calendar_intent_overlap_cases.py - "서비스 코드 수정 없이 관찰" 목적, 수동 실행
  2. test_calendar_query_vs_create.py - python3 직접 실행, pytest 미적용
  3. test_all_day_event_simple.py - 수동 실행 스크립트
  4. e2e/test_e2e_message_flow.py - "pytest 없이 직접 실행" 주석, 중복 (test_message_flow_e2e.py 존재)

결과: 68개 → 64개 (pytest 자동 테스트만 유지)


10. 참고

  • FastAPI 구조 원칙: 311_백엔드_구조_원칙.md 섹션 18 (테스트 원칙)
  • 문서 작성 원칙: 312_문서_작성_원칙.md (troubleshooting 기록 방법)
  • 트러블슈팅: journey/troubleshooting/251110_레거시_테스트_폴더_정리.md