DOCS/book/300_architecture/315_테스트_작성_원칙.md
Claude-51124 5547b280ce docs: 테스트 작성 원칙 문서 보완
- pytest 자동 테스트 기준 섹션 추가 (섹션 6)
- pytest 없이 직접 실행하는 스크립트 금지 명시
- 중복 e2e 테스트 통합 규칙 추가
- 실제 정리 사례 추가 (섹션 9)
- 체크리스트에 pytest 검증 항목 추가
2026-01-03 12:59:57 +09:00

6.2 KiB

테스트 작성 원칙

작성일: 2025-01-03 참고: 311_FastAPI_구조_원칙.md, 312_문서_작성_원칙.md


1. 핵심 원칙

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

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

원칙:

  • 재사용성 우선: 공통 테스트 로직은 fixtures/유틸리티로 추출
  • 자동화 필수: pytest 기반 자동 테스트만 유지, 수동 스크립트는 작업 완료 즉시 삭제
  • 중복 제거: 동일 기능 테스트는 하나로 통합

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

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

금지 사항

금지 이유
tests/에 실험 스크립트 저장 자동 테스트와 혼재, 정리 어려움
수동 실행 스크립트 장기 보관 재작성 비효율 유발
중복 테스트 파일 유지 유지보수 비용 증가

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 기록 후 삭제

유지 기준

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

5. 임시 테스트 정리

즉시 삭제 대상

  1. 리팩토링 테스트: test_*_refactoring.py (작업 완료 후)
  2. 비교 실험: test_*_vs_*.py (결과 troubleshooting에 기록 후)
  3. 관찰용 스크립트: "서비스 코드 수정 없이 관찰" 목적의 스크립트
  4. 실험 결과 파일: .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

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. 체크리스트

테스트 작성 전

  • 동일한 테스트 로직이 이미 존재하는가? (재사용 가능한지 확인)
  • 공통 모킹/데이터가 있다면 conftest.py에 추가할 수 있는가?
  • pytest 자동 테스트인가? (수동 스크립트면 scripts/ 사용)
  • import pytest 또는 @pytest 데코레이터 포함? (섹션 6 기준)

테스트 파일 추가 전

  • 중복 테스트 파일이 있는가? (통합 가능한지 확인)
  • 임시 실험 파일인가? (작업 완료 시 삭제 계획 수립)
  • 네이밍 규칙 준수 (test_{기능}.py)
  • pytest tests/test_*.py 명령으로 실행 가능한가?

정리 시점

  • 리팩토링/비교 테스트 → troubleshooting 기록 후 삭제
  • 실험 스크립트 → 작업 완료 즉시 삭제
  • 중복 테스트 → 통합 또는 삭제
  • pytest 없이 직접 실행하는 파일 → 삭제 또는 pytest로 변환

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_FastAPI_구조_원칙.md 섹션 18 (테스트 원칙)
  • 문서 작성 원칙: 312_문서_작성_원칙.md (troubleshooting 기록 방법)
  • 트러블슈팅: journey/troubleshooting/251110_레거시_테스트_폴더_정리.md