diff --git a/book/300_architecture/300_README.md b/book/300_architecture/300_README.md index 1ac6125..f7f57f8 100644 --- a/book/300_architecture/300_README.md +++ b/book/300_architecture/300_README.md @@ -13,6 +13,7 @@ Part 2에서 우리는 게임 메커니즘을 활용한 설계를 소개했습 - 311_FastAPI_구조_원칙.md - 312_문서_작성_원칙.md - 313_React_구조_원칙.md +- 315_테스트_작성_원칙.md - 320_Slack_기반_인터페이스_설계.md - 330_백엔드_PostgreSQL_ChromaDB_Vector_Memory.md - 340_GUI_공유_아키텍처_레벨기반_권한.md diff --git a/book/300_architecture/315_테스트_작성_원칙.md b/book/300_architecture/315_테스트_작성_원칙.md new file mode 100644 index 0000000..f28eea7 --- /dev/null +++ b/book/300_architecture/315_테스트_작성_원칙.md @@ -0,0 +1,150 @@ +# 테스트 작성 원칙 + +**작성일**: 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 사용 +```python +# 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. 테스트 네이밍 및 구조 + +### 파일명 규칙 + +| 패턴 | 용도 | 예시 | +|------|------|------| +| `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/ 폴더로 이동) + +--- + +## 7. 체크리스트 + +### 테스트 작성 전 + +- [ ] 동일한 테스트 로직이 이미 존재하는가? (재사용 가능한지 확인) +- [ ] 공통 모킹/데이터가 있다면 `conftest.py`에 추가할 수 있는가? +- [ ] pytest 자동 테스트인가? (수동 스크립트면 `scripts/` 사용) + +### 테스트 파일 추가 전 + +- [ ] 중복 테스트 파일이 있는가? (통합 가능한지 확인) +- [ ] 임시 실험 파일인가? (작업 완료 시 삭제 계획 수립) +- [ ] 네이밍 규칙 준수 (`test_{기능}.py`) + +### 정리 시점 + +- [ ] 리팩토링/비교 테스트 → troubleshooting 기록 후 삭제 +- [ ] 실험 스크립트 → 작업 완료 즉시 삭제 +- [ ] 중복 테스트 → 통합 또는 삭제 + +--- + +## 8. 참고 + +- FastAPI 구조 원칙: `311_FastAPI_구조_원칙.md` 섹션 18 (테스트 원칙) +- 문서 작성 원칙: `312_문서_작성_원칙.md` (troubleshooting 기록 방법) +- 트러블슈팅: `journey/troubleshooting/251110_레거시_테스트_폴더_정리.md` +