21 KiB
0. 문서 상태
이 문서의 현재 상태와 식별 정보를 기록한다. 문서 추적과 승인 흐름에 필요한 최소 메타데이터를 적는다.
- 상태: confirmed
- 문서 ID: dcy-006_20260630_pytest-apptest-smoke-ci-automation
- 이슈명: pytest/AppTest/Smoke CI 자동화
- 작성 시각(KST): 2026-06-30 13:32
- 마지막 갱신 시각(KST): 2026-06-30 14:42 KST
- 대체됨: 없음
- 후속 Discovery 참조: 없음
- 생성된 REQ 참조: REQ-006 (
docs/srs/Testing/req-006_pytest-apptest-smoke-ci-automation.md)
1. 계획 상태 요약
현재 Discovery가 어떤 배경에서 작성되고 있는지, 연계 문서가 있는지, 지금 시점의 해석이 무엇인지 짧게 요약한다.
- 연계 문서 현황:
- 관련 GitHub Project 항목: https://github.com/users/genichin/projects/4 의
pytest/AppTest/Smoke CI 자동화항목 (Project #4 잔여 작업) - 선행 Discovery:
docs/discovery/dcy-004_20260629_browser-streamlit-e2e-evidence-recovery.md(Out of Scope/체크리스트에서 CI 통합을 본 항목으로 분리)
- 관련 GitHub Project 항목: https://github.com/users/genichin/projects/4 의
- 해석:
- dcy-004는 로컬 재현 가능한 browser evidence 복구까지로 범위를 한정하고,
pytest/AppTest/Smoke CI 자동화를 Project #4의 별도 항목으로 명시적으로 분리했다. 본 Discovery는 그 분리된 후속 작업을 독립 주기로 끌어올려 추적한다. - 현재 저장소에는 pytest 회귀 스위트, Streamlit AppTest, HTTP/DB safety smoke 자산이 이미 존재하지만 이를 강제 실행·게이트화하는 CI 계약(workflow)이 전혀 없다. 본 Discovery는 "이미 있는 검증 자산을 CI로 자동 실행·게이트화하는 계약"을 정의하는 것을 목표로 한다.
- dcy-004는 로컬 재현 가능한 browser evidence 복구까지로 범위를 한정하고,
2. 요구사항 판정 결과
이번 요청이 기존 요구사항과 비교해 신규인지, 유사한지, 중복인지 판단하고 그 근거를 남긴다.
- 판정: 신규
- 근거
- dcy-004는 browser-level evidence 복구와 QC evidence 등급 정의가 중심이며, "검증 자산을 CI에서 자동 실행·게이트화"하는 자동화 계약을 독립 성공 기준으로 다루지 않았다. dcy-004 본문(
# 5 범위 경계,# 8 확인 체크)이 CI 통합을 본 항목으로 명시 분리했다. - 저장소에
.github/workflows/가 존재하지 않고docs/project-structure.md도 "CI workflow and deployment/service management are not yet defined."로 기록한다. 따라서 CI 자동화는 기존 요구사항의 미세 조정이 아니라 신규 governance unit이다.
- dcy-004는 browser-level evidence 복구와 QC evidence 등급 정의가 중심이며, "검증 자산을 CI에서 자동 실행·게이트화"하는 자동화 계약을 독립 성공 기준으로 다루지 않았다. dcy-004 본문(
3. 문제점의 요약
문제의 현재 상태, 기대 상태, 관련 이해관계자, 제약사항을 정리한다. Discovery의 핵심 맥락을 가장 먼저 이해할 수 있어야 한다.
- 현재 상태
- CI 계약이 부재하다: 저장소에
.github/workflows/디렉터리 자체가 없어, push/PR 시 자동으로 테스트를 실행·차단하는 게이트가 존재하지 않는다. 검증은 전적으로 작성자/검수관의 수동 로컬 실행에 의존한다.docs/project-structure.md도 "CI workflow and deployment/service management are not yet defined."로 명시한다. - 검증 자산은 이미 풍부하다: pytest 회귀 스위트(
tests/test_categorization.py,tests/test_service.py,tests/test_backup_workflow.py,tests/test_dashboard_app.py등 11개 테스트 모듈),pyproject.toml의[tool.pytest.ini_options](testpaths=["tests"], dev extra의pytest>=8.0.0)가 갖춰져 있다. 그러나 이들을 자동 실행하는 외부 계약이 없다. - AppTest/smoke 자산이 로컬에 묶여 있다: Streamlit
AppTest기반tests/test_dashboard_app.py, browser evidence 스크립트scripts/streamlit_browser_evidence.py, DB restore safety smokescripts/ledger_restore_smoke.py가 존재하지만 모두 로컬 수동 실행이 전제다.docs/project-structure.md는 "Local browser evidence capture exists ... broader flow coverage and CI automation remain planned."로 이 한계를 기록한다. - browser evidence가 로컬 한정이다: dcy-004 결과로
/usr/bin/google-chrome-stable기반 로컬 browser evidence 절차는 복구됐으나, 이는 헤드리스 Chrome/snap 가용성에 의존해 CI runner로 그대로 이식하기 어렵다. 따라서 CI 1차 게이트는 browser-screenshot이 아니라 결정적으로 실행 가능한 pytest/AppTest/HTTP/DB safety smoke로 구성해야 한다.
- CI 계약이 부재하다: 저장소에
- 기대 상태
- push/PR 시 pytest 회귀 스위트, Streamlit AppTest, HTTP smoke, DB safety smoke가 CI에서 자동 실행되어 합격/불합격이 게이트로 강제된다.
- CI 계약이 문서화된 단일 진입점(workflow 정의)으로 존재하고, 어떤 검증이 blocker이고 어떤 것이 best-effort인지 명확히 구분된다.
- browser-level evidence처럼 환경 의존이 큰 검증은 CI 필수 게이트에서 분리하고, 로컬/수동 evidence 절차(dcy-004)와의 경계가 명확히 정의된다.
- 이해관계자
- 렛저장인(운영자 겸 작성자) — CI workflow를 구성·유지하고 로컬 검증과의 경계를 운영하는 주체
- 검수관/리뷰어 — CI 게이트 결과를 QC gate 판정의 1차 근거로 사용하는 주체
- StagePilot 후속 SDLC(REQ/Batch) 수행자 — 본 Discovery를 CI 자동화 요구사항으로 정제
- 제약사항
- 개인 금융정보를 다루므로 CI 실행 로그·아티팩트에 실계좌번호·잔액·raw_payload·원본 파일명 등 민감정보가 노출되어서는 안 된다. CI 검증은 synthetic fixture를 우선 사용한다.
- CI runner는 헤드리스 browser/snap 가용성이 보장되지 않으므로, browser-screenshot E2E를 CI 필수 게이트로 강제하지 않는다(dcy-004 evidence 등급의 fallback 경로를 CI 맥락에서 재해석).
- DB safety smoke는 운영 DB가 아니라 임시 fixture/검증 DB(dcy-002 절차)에서만 수행하여 원본 데이터를 훼손하지 않아야 한다.
주요 사용자 시나리오
사용자 또는 운영자가 실제로 어떤 상황에서 이 변경을 필요로 하는지 대표 시나리오를 적는다.
- 작성자가 분류/서비스/백업 로직을 변경해 PR을 올리면, CI가 pytest 회귀 스위트를 자동 실행하고 실패 시 머지를 차단해 회귀를 조기에 잡는다.
- 작성자가
dashboard/app.py를 변경하면, CI가 Streamlit AppTest와 HTTP smoke를 fixture DB로 실행해 대시보드가 기동·렌더링되는지 자동 검증한다. - 검수관이 batch verification을 작성할 때, CI 게이트 통과 로그를 1차 evidence로 인용하고, browser-screenshot evidence는 환경이 허용하는 로컬 절차(dcy-004)에서 보강한다.
- 백업/복구 로직을 변경하면, CI가 DB safety smoke(
scripts/ledger_restore_smoke.py계열)를 임시 fixture DB로 실행해 복구 절차가 운영 DB를 건드리지 않고 통과하는지 확인한다.
4. 이번에 정의할 변경
이번 Discovery에서 다루는 핵심 변경 항목을 목록으로 적는다. 기능, 구조, 규칙 변경을 함께 포함해도 된다.
- pytest 회귀 스위트를 push/PR에서 자동 실행하는 CI 계약(workflow)을 신설한다. 어떤 이벤트에서 어떤 job이 실행되고 무엇이 머지 blocker인지 정의한다.
- Streamlit AppTest와 HTTP smoke, DB safety smoke를 CI job으로 자동화한다. 모두 synthetic fixture/임시 검증 DB에서 결정적으로 실행되도록 표준화한다.
- CI 필수 게이트와 환경 의존 검증(browser-screenshot E2E)의 경계를 규칙으로 정의한다. browser evidence는 CI 필수 게이트에서 분리하고 로컬 절차(dcy-004)와의 역할을 문서화한다.
- CI 계약과 검증 job 구조를 baseline 문서에 반영한다:
docs/project-structure.md의 "CI workflow ... not yet defined" 항목을 갱신하고,docs/runtime-flows.md에 CI 검증 흐름을 추가할 필요를 명시한다.
영향 범위
변경이 미칠 코드/문서/운영 범위를 명시해 REQ 정제와 batch planning에서 추정 누락을 줄인다.
- 코드 영향:
.github/workflows/— CI workflow 정의 신설(파일 경로/이름은 REQ/Batch에서 확정). pytest, AppTest, HTTP smoke, DB safety smoke job 구성.scripts/— 기존ledger_restore_smoke.py,streamlit_browser_evidence.py를 CI에서 호출 가능한 결정적 진입점으로 재사용/래핑할 가능성. HTTP smoke 전용 헬퍼 신설 여부는 후속 범위.tests/— 기존 pytest/AppTest 자산은 보존. CI에서 fixture DB를 결정적으로 준비하는 공용 유틸 추가 가능성.pyproject.toml— CI 실행에 필요한 dev/dashboard extra 설치 경계 확인(이미dev=pytest,dashboard=streamlit/pandas/plotly 존재).
- 문서 영향:
docs/project-structure.md— "CI workflow and deployment/service management are not yet defined." 및 "CI automation remain planned." 항목 갱신.docs/runtime-flows.md— CI 검증 흐름(이벤트 → job → 게이트 결과) 추가.docs/interface-contract.md— CI 게이트 결과를 QC evidence로 인용하는 기준 반영 검토.docs/runbooks/— CI 실패 대응/로컬 재현 runbook 후보.
- 운영 영향:
- push/PR마다 자동 검증이 실행되어 수동 로컬 실행 의존도가 낮아진다.
- QC gate 운영에서 CI 통과 로그가 1차 evidence로 표준화되고, browser evidence는 환경 허용 시 보강 증거로 운영된다.
5. 요구사항 목록
실제로 구현과 검증으로 이어질 요구사항을 기능/비기능으로 나누어 정리하고, 범위 경계를 명확히 적는다.
기능 요구사항
- FR-1: push/PR 이벤트에서 pytest 회귀 스위트(
testpaths=["tests"])를 자동 실행하고, 실패 시 머지 blocker로 동작하는 CI workflow를 제공해야 한다. - FR-2: Streamlit
AppTest(tests/test_dashboard_app.py계열)와 대시보드 HTTP smoke(고정 포트로 기동 후 HTTP 200 확인)를 synthetic fixture DB로 CI에서 자동 실행해야 한다. - FR-3: DB safety smoke(
scripts/ledger_restore_smoke.py계열)를 임시 fixture/검증 DB에서 CI job으로 실행하여, 복구 절차가 원본 운영 DB를 건드리지 않고 통과하는지 자동 검증해야 한다. - FR-4: CI 필수 게이트(pytest/AppTest/HTTP/DB safety smoke)와 환경 의존 검증(browser-screenshot E2E)을 명확히 구분하고, browser evidence는 CI 필수 게이트에서 제외하되 로컬 절차(dcy-004)와의 역할을 문서화해야 한다.
- FR-5: CI 계약과 검증 job 구조를
docs/project-structure.md와docs/runtime-flows.md에 반영하고("CI workflow ... not yet defined" 항목 갱신), 필요 시 CI 실패 대응 runbook 후보를docs/runbooks/에 추가해야 한다.
비기능 요구사항
성능, 운영성, 일관성, 자동화 안정성 등 기능 외 요구사항을 적는다.
- NFR-1: CI 검증은 결정적이어야 한다. 동일 커밋에 대해 동일 결과를 산출하도록 synthetic fixture·고정 포트/경로·로드 완료 대기 조건을 표준화한다(flaky job 최소화).
- NFR-2: CI 로그·아티팩트에 실계좌번호·잔액·raw_payload·원본 파일명·비밀번호 등 민감정보가 평문으로 노출되어서는 안 되며, 모든 CI 검증은 synthetic fixture를 우선 사용한다.
- NFR-3: CI는 운영 DB를 절대 사용하지 않고 임시 fixture/검증 DB(dcy-002 절차)에서만 동작하여 원본 데이터 훼손 위험이 없어야 한다.
- NFR-4: CI runner의 browser/snap 가용성에 의존하지 않고도 필수 게이트가 통과 가능해야 한다(headless browser는 best-effort, 필수 게이트는 pytest/AppTest/HTTP/DB safety smoke).
범위 경계
이번 반복에서 반드시 포함할 범위와 명시적으로 제외할 범위를 구분한다.
- In Scope
- pytest 회귀 스위트, Streamlit AppTest, 대시보드 HTTP smoke, DB safety smoke를 push/PR에서 자동 실행하는 CI 계약 정의
- CI 필수 게이트와 환경 의존(browser) 검증의 경계 규칙 정의 및 baseline 문서 반영
- synthetic fixture 우선·민감정보 금지·운영 DB 미사용 원칙의 CI 적용
- Out of Scope
- browser-screenshot/visual regression의 CI 필수 게이트화(환경 의존이 커 best-effort로만 검토). 로컬 browser evidence는 dcy-004 범위로 유지.
- 배포/릴리스 자동화(CD), 외부 호스팅/서비스 운영 도입. 본 반복은 검증 CI 게이트까지로 한정.
- 테스트 커버리지 목표치 강제, 성능 벤치마크 게이트 같은 고도화 품질 게이트는 후속 반복으로 분리.
- CI 플랫폼은 GitHub Actions로 고정하고, 기본 트리거는
pull_request와main대상push, 선택 경로는workflow_dispatch로 둔다.
6. 리스크/가정 목록
불확실성과 전제 조건을 분리해서 적는다. 리스크는 영향과 완화 방안을, 가정은 현재 판단의 전제를 기록한다.
리스크
- R-1 (Medium): Streamlit AppTest/HTTP smoke가 동적 렌더링·비동기 로딩으로 CI에서 비결정적으로 실패(flaky)하면 게이트 신뢰도가 떨어진다.
- 완화 방안: 결정적 synthetic fixture DB, 고정 포트, 기동 후 readiness 대기(HTTP 200 폴링) 조건을 표준화하고, 재시도/타임아웃 정책을 명시한다.
- R-2 (Medium): CI 실행 중 fixture 준비나 로그 출력에 실데이터/민감정보가 섞이면 외부 CI 로그에 평문 노출될 수 있다.
- 완화 방안: 모든 CI 검증을 synthetic fixture로 고정하고 운영 DB 경로 접근을 차단한다. 로그/아티팩트 마스킹 및 민감 필드 공란 원칙을 검증 단계에 포함한다.
- R-3 (Low): browser evidence를 CI 필수 게이트로 무리하게 끌어들이면 runner 환경 제약으로 게이트가 상시 실패할 수 있다.
- 완화 방안: browser-screenshot E2E를 필수 게이트에서 제외하고 best-effort/로컬 절차로 분리하는 경계 규칙을 명시한다.
가정
아직 확정되지 않았지만 현재 문서 작성의 기반이 되는 전제를 적는다.
- A-1: 기존 pytest 스위트,
tests/test_dashboard_app.py의 AppTest,scripts/ledger_restore_smoke.py,scripts/streamlit_browser_evidence.py자산을 CI에서 재사용 가능한 형태로 호출할 수 있다. - A-2: CI 필수 게이트는 headless browser 없이도 pytest/AppTest/HTTP smoke/DB safety smoke만으로 의미 있는 회귀 보호를 제공한다.
- A-3: DB safety smoke와 fixture 준비는 dcy-002의 백업·검증 DB 절차가 운영 가능한 상태임을 전제로 임시/복사본 DB에서 수행한다.
- A-4: synthetic fixture만으로 핵심 import/분류/대시보드 경로의 CI 검증이 가능하며, 실데이터 없이도 회귀를 충분히 포착할 수 있다.
오픈 질문
답을 아직 모르는 항목을 적는다. 추정으로 덮지 말고 REQ 초안 작성 이전에 확인할 질문으로 남긴다.
- OQ-1: CI 실행 플랫폼과 트리거 범위를 무엇으로 확정할 것인가(GitHub Actions push/PR vs 수동 dispatch vs 로컬 pre-commit 병행)?
- 상태: Answered
- 답변: GitHub Actions를 기본 CI 플랫폼으로 사용하고,
pull_request와main대상push를 기본 트리거로 하며workflow_dispatch를 선택적 수동 재실행 경로로 허용한다. - 반영 메모: REQ acceptance criteria에는 PR 기준 필수 게이트와
mainpush 재실행 기준, 선택적 수동 실행 허용을 포함한다.
- OQ-2: HTTP smoke와 DB safety smoke를 기존
scripts/자산을 그대로 CI에서 호출할지, CI 전용 결정적 진입점으로 별도 래핑할지?- 상태: Answered
- 답변: 기존
scripts/와 테스트 자산의 내부 로직은 재사용하되, CI에서는 종료코드·인자·로그가 결정적인 얇은 wrapper entrypoint를 별도로 둔다. - 반영 메모: REQ/Batch 설계 시 smoke job은 CI 전용 wrapper를 표준 진입점으로 사용하고, 기존 자산은 내부 구현으로 재사용한다.
7. 초기 성공 기준
이 변경이 성공했다고 판단할 기준을 측정 가능하게 정의한다. 가능하면 데이터 출처까지 연결한다.
- S-1: push/PR 이벤트에서 pytest 회귀 스위트가 CI로 자동 실행되고, 의도적으로 깨진 변경에 대해 게이트가 머지를 차단함을 재현 가능하게 확인한다.
- S-2: Streamlit AppTest, HTTP smoke, DB safety smoke가 synthetic fixture/임시 검증 DB로 CI에서 통과하고, 실행 로그·아티팩트에 민감정보가 노출되지 않음을 확인한다.
- S-3: CI 필수 게이트와 browser evidence 경계, CI 검증 흐름이
docs/project-structure.md("CI workflow ... not yet defined" 갱신)와docs/runtime-flows.md에 반영되어 후속 REQ/Batch에서 참조 가능하다.
측정 방식 및 데이터 출처
각 성공 기준을 어떻게 측정할지와 어떤 데이터나 문서를 근거로 쓸지 적는다.
- S-1 측정 방식: CI 실행 결과(성공/실패) 로그와, 의도적 회귀 주입 시 게이트가 fail하는지 재현 확인 / 데이터 출처: CI workflow 실행 로그, pytest 결과
- S-2 측정 방식: AppTest/HTTP/DB safety smoke job의 통과 로그 확인 및 로그·아티팩트의 민감정보 미노출 검수 / 데이터 출처: CI job 로그·아티팩트, synthetic fixture DB
- S-3 측정 방식: baseline 문서 갱신 및 CI 검증 흐름 반영 여부 리뷰 / 데이터 출처:
docs/project-structure.md,docs/runtime-flows.md,docs/runbooks/
8. REQ로 넘기기 전 확인 체크
REQ 초안 작성 단계로 넘기기 전에 무엇이 확정되어야 하는지 확인한다. 미완료 항목은 후속 결정이 필요함을 뜻한다.
- 범위(In Scope/Out of Scope) 확정
- 기준: 본 반복은 검증 CI 게이트(pytest/AppTest/HTTP/DB safety smoke)까지로 한정하고 CD·visual regression·커버리지 게이트는 제외한다는 점을 사용자가 확인한다.
- 성공 지표의 측정 방식/데이터 출처 확정
- 기준: CI 실행 로그·아티팩트·synthetic fixture가 acceptance criteria의 측정 근거로 확정된다.
- High 영향 리스크 우선순위 및 해소 책임자 지정
- 기준: flaky 위험(R-1)과 민감정보 노출(R-2) 완화 책임자를 지정한다. 본 Discovery에 현재 High 리스크는 없으나 R-1/R-2를 우선 관리한다.
- 모든 오픈 질문(OQ)
Open상태 없음 확인- 기준: OQ-1(CI 플랫폼/트리거), OQ-2(smoke 진입점 재사용 vs 래핑)가 모두 Answered로 정리되었다.
- Freeze 확정 담당자(CONFIRMED_BY) 지정
- 기준: 사용자(진환 고)가 권장안을 승인했다.
9. 파일 처리 결과
이 Discovery 문서 생성/갱신 결과와 참조 문서를 기록한다. 이후 추적과 리뷰 시 근거로 사용한다.
- 처리 결과: 생성
- 생성 경로: docs/discovery/dcy-006_20260630_pytest-apptest-smoke-ci-automation.md
- 참조 문서:
- docs/discovery/dcy-004_20260629_browser-streamlit-e2e-evidence-recovery.md
- docs/project-structure.md
- docs/runtime-flows.md
- stage-pilot/templates/project-structure.md
- stage-pilot/templates/runtime-flows.md
10. 사용자 결정 필요 항목 요약
사용자나 승인자가 결정해야 하는 항목만 모아 정리한다. 결정, 확인, 데이터 요청을 구분해서 적는다.
DECIDE
- CI 플랫폼은 GitHub Actions를 사용한다. 기본 트리거는
pull_request와main대상push이며,workflow_dispatch는 선택적 수동 재실행 경로로 허용한다. - HTTP smoke/DB safety smoke는 기존
scripts/와 테스트 자산을 내부적으로 재사용하되, CI에서는 종료코드·인자·로그가 결정적인 얇은 wrapper entrypoint를 표준으로 사용한다.
CONFIRM
- CI 필수 게이트는
pytest,Streamlit AppTest,HTTP smoke,DB safety smoke로 한정한다. browser-screenshot E2E는 필수 차단 게이트에 넣지 않고 로컬 보강 evidence 절차(dcy-004)로 유지한다.
DATA
- CI는 매 실행 시 생성되는 synthetic fixture DB만 사용한다. 운영 DB는 사용하지 않으며 실계좌번호·실잔액·
raw_payload·원본 파일명·비밀번호는 포함하지 않는다. - synthetic fixture DB는 계좌/거래/확인필요 큐/월간 현금흐름/복구 smoke가 모두 재현 가능한 최소 결정적 샘플 세트를 포함하고, runner temp 경로 또는 동등한 임시 경로에 생성한다.
11. Discovery Freeze
REQ 초안 작성 인계 시점의 확정 플래그와 섹션 참조만 기록한다. 내용 재작성 없이 원본 섹션을 링크로 대신한다.
섹션 참조
- 범위: # 5. 요구사항 목록 > 범위 경계
- 리스크/오픈 질문: # 6. 리스크/가정 목록
- 성공 기준: # 7. 초기 성공 기준
- 인계 전 확인: # 8. REQ로 넘기기 전 확인 체크
- 사용자 결정 필요: # 10. 사용자 결정 필요 항목 요약
Freeze 플래그
- Handoff Decision: 승인
- Handoff Rationale: 사용자가 권장 기본안(GitHub Actions + CI 전용 얇은 smoke wrapper + pytest/AppTest/HTTP/DB safety smoke 필수 게이트 + synthetic fixture DB 정책)을 승인해 사람 결정 항목이 해소되었다. 남은 책임자 지정은 REQ/Batch planning 단계에서 할당 가능한 운영 항목이며 Discovery confirm을 막지 않는다.
- Ready for REQ Drafting: true
- Confirmed By: 진환 고
- Confirmed At (KST): 2026-06-30 13:54 KST