# REQ-006 pytest/AppTest/Smoke CI 자동화 - Status: Implemented - Type: Testing - Priority: High - Owner: 렛저장인 - Source Discovery: `docs/discovery/dcy-006_20260630_pytest-apptest-smoke-ci-automation.md` - Batch: BAT-006 - Created At (KST): 2026-06-30 14:42 KST - Approved At (KST): 2026-06-30 14:50 KST - Implemented At (KST): 2026-06-30 15:29 KST ## 1. 배경 현재 저장소에는 `pytest` 회귀 스위트, Streamlit `AppTest`, 대시보드 HTTP smoke, DB restore safety smoke 자산이 이미 존재하지만, 이를 `push`/`pull_request`에서 자동 실행해 머지를 차단하는 CI 계약이 없다. 그 결과 회귀 검증은 작성자와 검수관의 수동 로컬 실행에 의존하고, browser evidence 복구(dcy-004)와 dashboard 운영 허브(dcy-005)에서 확보한 검증 자산도 반복 가능한 게이트로 고정되지 못했다. dcy-006 confirmed Discovery에 따라 GitHub Actions 기반 CI를 도입하고, 결정적 synthetic fixture DB를 사용해 `pytest`/`AppTest`/`HTTP smoke`/`DB safety smoke`를 자동 실행하는 표준을 정의한다. ## 2. 범위 ### In Scope - GitHub Actions 기반 CI workflow를 신설하고 `pull_request`, `main` 대상 `push`, 선택적 `workflow_dispatch` 트리거를 정의한다. - 필수 게이트를 `pytest`, Streamlit `AppTest`, 대시보드 HTTP smoke, DB safety smoke로 구성한다. - CI에서는 기존 테스트/스크립트 자산의 내부 로직을 재사용하되, 종료코드·인자·로그가 결정적인 얇은 wrapper entrypoint를 표준 진입점으로 사용한다. - 모든 CI 검증은 매 실행 시 생성되는 synthetic fixture DB 또는 임시 검증 DB에서 수행하고 운영 DB 접근을 금지한다. - `docs/project-structure.md`, `docs/runtime-flows.md`, 필요 시 `docs/runbooks/`를 갱신해 CI 게이트와 로컬 browser evidence(dcy-004) 경계를 문서화한다. ### Out of Scope - browser-screenshot/visual regression을 CI 필수 차단 게이트로 승격하는 작업. - 배포/릴리스 자동화(CD), 서비스 호스팅, 운영 프로세스 관리. - 테스트 커버리지 퍼센트 강제, 성능 벤치마크 게이트, flaky test quarantine 시스템 같은 고도화 품질 체계. - 운영 DB 또는 실거래/실계좌 데이터를 CI에 반입하는 작업. ## 3. 기능 요구사항 ### FR-1. GitHub Actions CI 진입점 - 저장소는 GitHub Actions workflow 파일을 제공해야 한다. - 기본 트리거는 `pull_request`와 `main` 대상 `push`여야 하며, `workflow_dispatch`는 선택적 수동 재실행 경로로 허용해야 한다. - 필수 검증 job 실패 시 workflow 전체가 실패해야 하며, PR 병합 차단 근거로 사용할 수 있어야 한다. ### FR-2. pytest 회귀 게이트 - CI는 저장소의 표준 pytest 회귀 스위트를 자동 실행해야 한다. - 실행 진입점은 로컬과 CI에서 동일한 의미를 가지도록 표준 명령 또는 wrapper로 고정해야 한다. - 실패 결과는 어떤 테스트가 실패했는지 식별 가능한 형태로 로그에 남겨야 한다. ### FR-3. Streamlit AppTest + HTTP smoke 게이트 - CI는 `tests/test_dashboard_app.py` 계열 Streamlit `AppTest`를 synthetic fixture DB로 자동 실행해야 한다. - CI는 대시보드 HTTP smoke를 별도 job 또는 동일 단계에서 수행해, Streamlit 서버가 fixture DB 기준으로 기동되고 HTTP 200 응답을 반환하는지 확인해야 한다. - HTTP smoke는 고정 또는 결정적으로 할당되는 포트, readiness 대기, timeout/정리 정책을 포함해야 한다. ### FR-4. DB safety smoke 게이트 - CI는 `scripts/ledger_restore_smoke.py` 계열 DB safety smoke를 임시 fixture/검증 DB에서 자동 실행해야 한다. - smoke는 운영 DB 기본 경로를 사용하지 않아야 하며, overwrite/restore 위험 동작은 명시적으로 차단되어야 한다. - smoke 실패 시 복구/검증 절차가 어떤 단계에서 실패했는지 로그로 식별 가능해야 한다. ### FR-5. CI 전용 wrapper entrypoint - HTTP smoke와 DB safety smoke는 기존 `scripts/`·테스트 자산의 내부 로직을 재사용하되, CI에서는 종료코드·입력 인자·출력 로그가 결정적인 얇은 wrapper entrypoint를 표준으로 사용해야 한다. - wrapper는 fixture 준비, 환경 변수 설정, readiness polling, timeout, 종료 후 정리를 일관되게 수행해야 한다. - wrapper는 민감정보가 섞일 수 있는 환경 변수/경로/데이터를 그대로 로그에 출력하지 않아야 한다. ### FR-6. CI 게이트와 browser evidence 경계 - CI 필수 게이트는 `pytest`, `Streamlit AppTest`, `HTTP smoke`, `DB safety smoke`로 한정해야 한다. - browser-screenshot E2E는 dcy-004의 로컬 보강 evidence 절차로 유지하고, CI 필수 차단 게이트에 포함하지 않아야 한다. - 문서에는 어떤 변경이 CI 필수 게이트만으로 충분한지, 어떤 경우에 로컬 browser evidence를 추가해야 하는지 경계를 설명해야 한다. ### FR-7. 기준선 문서 정렬 - `docs/project-structure.md`는 CI workflow와 관련 스크립트/wrapper 책임을 반영해야 한다. - `docs/runtime-flows.md`는 PR/push → CI jobs → gate result 흐름과 synthetic fixture DB 원칙을 반영해야 한다. - 필요 시 `docs/runbooks/`에 CI 실패 시 로컬 재현 절차 또는 smoke 실행 절차를 추가해야 한다. ## 4. Acceptance Criteria - AC-1: `.github/workflows/` 아래에 GitHub Actions workflow가 생성되고, `pull_request`, `main` 대상 `push`, `workflow_dispatch` 트리거가 정의된다. - AC-2: CI에서 pytest 회귀 스위트가 자동 실행되고, 단일 테스트 실패 시 workflow가 실패 상태로 종료된다. - AC-3: CI에서 Streamlit `AppTest`가 synthetic fixture DB 기준으로 자동 실행되고 통과/실패 결과가 로그에 남는다. - AC-4: CI에서 대시보드 HTTP smoke가 fixture DB 기준으로 Streamlit을 기동한 뒤 HTTP 200 응답을 확인하고, 종료 후 프로세스를 정리한다. - AC-5: CI에서 DB safety smoke가 운영 DB 기본 경로를 사용하지 않고 임시 fixture/검증 DB에서 통과한다. - AC-6: HTTP smoke/DB safety smoke는 CI 전용 wrapper entrypoint를 통해 실행되며, wrapper가 종료코드·timeout·readiness·cleanup을 일관되게 처리한다. - AC-7: CI 로그·아티팩트에는 실계좌번호, 실잔액, `raw_payload`, 원본 금융 파일명, 비밀번호가 평문으로 포함되지 않는다. - AC-8: `docs/project-structure.md`와 `docs/runtime-flows.md`가 CI 게이트와 로컬 browser evidence 경계를 반영한다. - AC-9: browser-screenshot E2E는 CI 필수 차단 게이트에서 제외되고, dcy-004 로컬 evidence 절차와의 역할 분담이 문서에 명시된다. ## 5. 구현 메모 - 이 REQ는 테스트/검증 계약과 운영 문서를 함께 다루는 `Testing` 타입으로 관리한다. - CI는 synthetic fixture DB를 매 실행마다 새로 생성하는 방식을 기본으로 하며, repo에 실데이터 기반 fixture를 커밋하지 않는다. - PR 병합 차단의 실제 enforcement(브랜치 보호 규칙)는 GitHub 설정과 연동되므로, workflow 설계 시 required check 이름이 안정적으로 유지되도록 한다. - `scripts/streamlit_browser_evidence.py`는 CI 필수 게이트가 아니라 로컬 보강 evidence 경로로 유지한다. - 리스크 책임자 지정과 batch 단위 구현 분해는 BAT-006 planning 단계에서 확정한다. - 이 REQ는 BAT-006 구현 및 `jarcaledgerqc`의 PASS_WITH_NOTES 검증을 근거로 Implemented로 전환했다. 남은 note는 원격 GitHub Actions 실행/required check 설정 확인으로, 저장소 코드 범위를 넘는 운영 확인 항목이다.