4. 통합 테스트 스위트
TL;DR
시험 D-1 시점에 운영 코드(src/kpi/*, src/pipelines/*, src/metrics/*)의 end-to-end 흐름과 API 진입점을 결정적 stub 모드 통합 테스트 23 개로 잠갔습니다. baseline 7 JSON 으로 회귀 감지, CI integration step 신설 (실패 시 차단). 운영 alpha 배포 흐름 영향 0.
신규 테스트23 (KPI 7 + API 16)
baseline JSON7
3회 회귀100% pass
실행 시간1.3 초
외부 API0
변경+930 / -2 (20 files)
4.1 사전 점검에서 발견된 핵심 위험 3개
| # | 위험 | 영향 | 대응 |
|---|---|---|---|
| 1 | 기존 CI pytest ... \|\| true | 실패해도 CI 통과 → 새 테스트 깨져도 머지 | 신규 integration step 추가 (\|\| true 미적용) |
| 2 | KPI4 stub 10,000 sample × 60s × 5 | CI 30s timeout 초과 | 통합테스트에서 evaluate(duration_sec=1, repeat=1) 축소 → 0.05 초 |
| 3 | KPI3/6 stub random.Random() 새 인스턴스 | score baseline 비교 false-positive | 해당 KPI baseline 은 schema · 메타만 잠금 (KPI4 패턴) |
4.2 신설 파일 구조
tests/ ├─ integration/ │ ├─ __init__.py │ ├─ conftest.py # baseline helper · RESULTS_DIR tmp · deterministic env │ ├─ test_kpi1_e2e.py # KPI ① 재무 F1 │ ├─ test_kpi2_e2e.py # KPI ② 분류 │ ├─ test_kpi3_e2e.py # KPI ③ BLEU │ ├─ test_kpi4_e2e.py # KPI ④ 처리속도 (축소 1s×1) │ ├─ test_kpi5_e2e.py # KPI ⑤ 개인화 │ ├─ test_kpi6_e2e.py # KPI ⑥ NQ │ ├─ test_kpi7_e2e.py # KPI ⑦ 상품추천 │ └─ test_api_e2e.py # TestClient — /api/health · /api/kpi · personas · sample └─ baselines/ ├─ kpi1_finance_qa.json # 5.7 KB · full result dict ├─ kpi2_text_classification.json # 1.3 KB ├─ kpi3_translation.json # 0.09 KB (schema only) ├─ kpi4_throughput.json # 0.12 KB (schema + integrity) ├─ kpi5_personalized_recommendation.json # 1.4 KB ├─ kpi6_finance_search.json # 0.09 KB (schema only) └─ kpi7_product_recommendation.json # 1.5 KB
4.3 통합 테스트 설계 원칙
- 운영 production code path 그대로 호출 — monkeypatch 는 dataset 크기만 축소.
src/pipelines/*stub 분기 +src/metrics/*·src/kpi/_common모두 실제 실행. - 외부 API 0 —
conftest._clear_ai_secretsautouse 가 모든 secret env 제거. ENABLE_*_PIPELINE=false → 모든 KPI 가 stub 분기. - 결정성 — SEED=20260514 + 시드 random.seed. KPI3/6 score 는 stub random 인스턴스 한계로 baseline 제외, schema·메타만 잠금.
- results 격리 — RESULTS_DIR autouse fixture 로
tmp_path/results격리. 운영 results 오염 없음. - baseline —
tests/baselines/{kpi}.json· UPDATE_BASELINES=1 로 의도 갱신.
4.4 baseline 비교 helper (conftest.py)
VOLATILE_KEYS = {
"timestamp", "results_path",
"elapsed_sec", "duration_sec", "duration_sec_actual",
}
def _strip_volatile(obj):
# dict / list 재귀로 비결정 필드 제거 후 baseline 과 비교
def assert_baseline_match(result, baseline_name):
cleaned = _strip_volatile(result)
if not path.exists() or os.getenv("UPDATE_BASELINES") == "1":
path.write_text(json.dumps(cleaned, ensure_ascii=False, indent=2, sort_keys=True))
pytest.skip(...)
expected = json.loads(path.read_text())
assert cleaned == expected
4.5 CI 통합 step (.github/workflows/ci.yml)
- name: install
run: |
pip install -r requirements-test.txt
pip install pytest-timeout
- name: compile check
run: python -m compileall -q src api
- name: smoke import
run: python -c "from src.api import app; print('routes:', len(app.routes))"
- name: pytest (unit only, fast)
run: python -m pytest tests/ --ignore=tests/integration -x --tb=short -q --timeout=30 || true
- name: pytest (integration, blocking — baseline + API E2E)
run: python -m pytest tests/integration/ -m integration --tb=short -q --timeout=120
4.6 회귀 검증
| 실행 | 결과 | 시간 |
|---|---|---|
| 1차 (UPDATE_BASELINES=1) | 23 skipped (baseline 생성) | 1.3 초 |
| 2차 | 23 passed | 1.3 초 |
| 3차 | 23 passed | 1.3 초 |
| 4차 | 23 passed | 1.3 초 |
| CI on PR #62 | 4 passed · 0 failed | ~1m |
4.7 머지 정책
- 시험 종료 (2026-05-20 17:30 예상) 까지 머지 보류.
- 시험 직후 또는 결과 PDF 수령 시점에 admin merge 권장.
- 운영 alpha 자동 배포 흐름 (
ci-cd-alpha.yml) 미변경 — 시험 직전 운영 흔들기 0.
4.8 KSEL 검토 관점에서의 가치
- 회귀 감지 — 시험 데이터셋 · 코드 변경에 따른 점수 변동 즉시 노출 (UPDATE_BASELINES 명시 안 하면 CI 차단)
- API 진입 schema 잠금 — KSEL 검토자가 시험 당일 호출할
/api/health9 필드 ·/api/kpi7 ID ·/api/personas6명 등 모두 자동 검증 - 결과 영속 검증 — KPI 모듈이 RESULTS_DIR 에 정확히 JSON 저장하는지 확인
- 외부 의존 0 — 시험 당일 외부 API 장애 (Anthropic / OpenAI) 와 무관하게 통합 흐름 자체 검증