8.0 KiB
8.0 KiB
테스트 원칙
작성일: 2025-01-03 수정일: 2026-02-04 (UX 검증 원칙 추가) 상위 원칙: 0_VALUE Coding Principles 참고: 311_backend_coding_principles.md, 312_writing-principles.md
1. 핵심 원칙
TDD 원칙
테스트는 TDD로 진행한다.
- Red: 테스트 먼저 작성 (기대 행동을 테스트에 명시)
- Green: 최소 구현으로 테스트 통과
- Refactor: 리팩터링 후 테스트 재실행
DecisionEngine, intent, 캘린더 로직 등은 항상 테스트에서 기대 행동을 확정한 뒤 수정한다.
로빙 테스트 환경 단일화 원칙
로빙(rb8001) 프로젝트 테스트는 rb8001/tests와 단일 실행 기준만 사용하고, 임시/분기 테스트 환경은 만들지 않는다.
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 |
.gitignore에 tests/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 문서화 후 |
정리 프로세스
- 문제 해결 → troubleshooting 문서 작성
- 핵심 교훈 기록
- 임시 테스트 파일 삭제
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_*.py와test_*_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)
삭제된 파일:
test_calendar_intent_overlap_cases.py- "서비스 코드 수정 없이 관찰" 목적, 수동 실행test_calendar_query_vs_create.py-python3직접 실행, pytest 미적용test_all_day_event_simple.py- 수동 실행 스크립트e2e/test_e2e_message_flow.py- "pytest 없이 직접 실행" 주석, 중복 (test_message_flow_e2e.py존재)
결과: 68개 → 64개 (pytest 자동 테스트만 유지)
10. 참고
- FastAPI 구조 원칙:
311_backend_coding_principles.md섹션 18 (테스트 원칙) - 문서 작성 원칙:
312_writing-principles.md(troubleshooting 기록 방법) - 트러블슈팅:
journey/troubleshooting/251110_레거시_테스트_폴더_정리.md