테스트의 긴 실패 대기를 줄이고 케이스 60초·동작 10초로 통합 — #1468 (2026-09-10)
- 기간: 2026-09-09~10, 작업 세션 1개와 HQ 통합. 오너 지시: “모든 테스트는 케이스 1건당 1분 이내 끝나도록”. 화면 전환·페이지 접속도 10초로 승인했다.
- 랜딩: 원 PR #1469의 구현 및 후속 수리를 통합 PR #1484, release
e56604cb0ae4d9fcaa361fbd99c3978dabb60535에 반영. staging PR #1488은213aaeb7에 병합됐다. 이 작업의 제품·DB·Edge 변경은 없으며 Production 배포는 당시 확인 전이다. - 설계서: 없음. 이슈 #1468의 승인된 시간 예산과 Phase 계획을 따른다.
- 정본: 테스트 시간 제한, 앱의 Playwright 설정·
tests/support/registerNodeTestBudget.mjs·e2e/support/connectivityRecoveryClock.mjs. - 도구: 저장소의 Node/Playwright 회귀 검사와 격리 DB 실행기. 임시 부분 재현 스크립트·로그는 작업 폴더에만 두고 제품 소스에 넣지 않았다.
- 게이트: 최종 full CI, 2026-09-10 00:59:39 KST 요약. runner의 격리 로컬 DB pgTAP 130파일/2,328 assert, 브라우저 56건, 화면 22건 통과. 작업 세션에서는 CASE-015/029/041/039/040만 필요한 시점에 부분 검증했다.
- 버그리포트: BUG-087 — 반복 복구 경과 시간을 기다리던 검사.
- 문서 정책은 앞서 docs PR #3으로 반영했다. 이 문서는 #1468 결과만 다루며 v0.17.7 전체 릴리스 보고서가 아니다.
Phase 현황
| Phase | 내용 | 상태 |
|---|---|---|
| Phase 1 | 케이스·브라우저 동작 제한과 자동 재시도 제거 | 통합 반영 |
| Phase 2 | Node 버전 호환·실행 경로·문서 기준 검증 | 통합 반영 |
| Phase 3 | 통합에서 드러난 반복 복구 검사 보완 | 통합 반영·전체 CI 통과 |
1. 배경
없는 화면 요소를 기다리는 실패 하나가 케이스 상한까지 이어지고, 자동 재시도 때문에 같은 실패를 다시 기다렸다. 오너는 기존 검증 내용과 사용자 여정을 유지하면서 케이스는 60초, 클릭·입력·전환·접속·내용 확인은 한 번에 10초 안에 끝나도록 요청했다.
2. 문제 제기
초기 화면 검사에서 표시되지 않은 홈 리포트 버튼을 기다리는 기존 관측은 240초씩 두 번이었다. 제한을 적용하자 같은 클릭은 10초에 실패했고 케이스는 14.258초에 종료됐다. 이때의 날짜 불일치는 기존 #1446·#1447 및 PR #1455의 수리가 검사 기준에 빠진 것이었다. 리포트 준비 단계도 #1460의 선행 수정이 필요했다. 두 건을 새 제품 결함으로 확대하지 않고 기존 수리의 통합을 기다렸다.
반복 연결 장애 검사 네 건은 제품의 정상적인 30초 probe 두 회를 실시간으로 기다리고 있었다. 이를 10초 대기로 바꾸기만 하면 의도된 경과 시간을 충족할 수 없다. 처음 제한을 줄일 때 이 반복 경로를 실제로 확인하지 못한 점은 사전 검증 누락으로 이슈에 기록했다.
3. 해결 방안
오너 결정은 60초/10초/자동 재시도 0회다. Node는 개별 케이스 등록에 예산을 적용하고 개별 준비를 본문에 포함했다. 파일·suite 전체와 공통 빌드·DB 준비·사후 정리는 구분한다. pgTAP 문장이나 CI job 제한을 일괄 변경하지 않았다.
| 안 | 판단 |
|---|---|
| 케이스·동작 예산을 실행 설정과 회귀 검사에 적용 | 채택. 실제 없는 대상의 10초 실패와 재시도 0회를 확인한다. |
| 긴 회복 간격은 테스트 시계로 진행하고 실제 응답 두 번을 확인 | 채택. 전체 저장·재조회·요청 본문 단언을 유지하며 경과 시간만 진행한다. |
| timeout을 다시 늘리거나 실패를 skip 처리 | 기각. 승인된 예산과 검증 범위를 훼손한다. |
| Node 22의 CLI timeout으로 파일 전체 제한 | 기각. 케이스 여러 건의 누적 실행까지 끊으므로 개별 상한의 의미와 다르다. |
4. 적용한 내용
Phase 1 — 실행 제한 통일
Node·Playwright 케이스 상한 60초, 브라우저 클릭·입력·전환·접속·내용/배치 대기 10초, 자동 재시도 0회를 적용했다. 1/100/1,000행 저장소 비용 검사는 기존 단언을 유지한 독립 세 건으로 나눴다.
Phase 2 — 호환성과 검증 경계
Node 22/24에서 등록 훅으로 케이스 타이머를 적용했다. 없는 클릭 대상의 실제 제한 종료, Node 취소 후 정리와 다음 케이스 실행을 확인했다. 공유 준비와 개별 준비의 경계를 문서에 명시했다.
Phase 3 — 반복 복구 검사 보완
CASE-015/029/041은 7b86ca59, CASE-039는 dbb12630에서 기존 사용자 여정을 보존한 채 회복 probe 간격만 테스트 시계로 진행한다. CASE-040 소스는 그대로 뒀다. 정상 queue처럼 NODE_ENV를 제거한 앱·실제 v0.17.1 legacy 빌드에서 039/040을 확인했다. 제품의 장애 대응 간격과 사용자 날짜 입력은 바꾸지 않았다.
작업 중 드러난 것
초기 부분 화면 검사는 18통과·2실패·2미실행이었다. 이 결과를 성공으로 바꾸거나 최종 성공 집합에 합산하지 않았다. 세부 시계 수리 과정에서도 015/029 통과와 마지막 수정 뒤 041 단독 통과를 구분했다. 최종 통합 full 실행은 이 개발 단계 결과와 별도의 증거다.
5. 적용 결과
| 항목 | 전 → 후 / 확인 범위 |
|---|---|
| 없는 홈 리포트 버튼 대기 | 기존 240초 × 2 관측 → 클릭 10초 실패·케이스 14.258초·retry 0. 환경이 달라 정상 CI 절감률로 일반화하지 않는다. |
| 초기 검증 | npm run check 3,408통과·DB 조건부 skip 27·실패 0. Node 22/24 관련 회귀 각 7/7. |
| 반복 복구 부분 검증 | 015 16.351초, 029 28.704초, 041 20.087초, 039 26.045초. 각각 retry 0으로 60초 이내 통과. 동일 실행 다섯 건의 합산 결과는 아니다. |
| 소스 변경 없는 CASE-040 | 정상 빌드 환경에서 19.010초·retry 0·skip 0 통과. |
| 최종 full 후보 | source 81d980352d44c443b5d8776154a7c44c980748f8, candidate e56604cb0ae4d9fcaa361fbd99c3978dabb60535, tree 12d339cd21d807000671f80e69de477e4d592d64. 검증한 merge commit 그대로 반영됐다. |
| 최종 full 결과 | 7분32초. 브라우저 56/56·화면 22/22, 각각 실패·skip·flaky 0. 단위 3,423통과·조건부 skip 30·실패 0. pgTAP 130파일/2,328 assert 통과. |
| 날짜·리포트 선행 수리 | 기존 수리가 포함된 최종 화면 검사 22건 모두 통과. #1468에서 중복 날짜 수리를 추가하지 않았다. |
| 릴리스 상태 | release/v0.17.7 및 staging 병합. 기록 시점 Production 배포 완료는 확인 전. |
위 시간은 full 실행기의 계측값이며 GitHub job 전체 시간과 다르다. 병렬화 등 다른 통합 변경도 포함되므로 7분32초를 #1468 단독 절감 효과로 주장하지 않는다. 모든 개별 테스트의 최대 실제 소요시간을 별도로 전수 추출한 결과도 아니다.
6. 이번 개선으로 향상된 것
실패한 대상은 짧은 대기 안에 원인을 남기고 종료하며 같은 실패를 자동으로 반복하지 않는다. 긴 제품 타이머를 다루는 검사도 실제 응답과 최종 저장 결과를 확인하면서 승인된 케이스 예산 안에서 실행한다. 이 경계는 실행 설정·회귀 검사·작성 기준에 남았다.
남은 것
앱 Production 반영 확인과 원 이슈 정리는 HQ의 배포 성공 신호 뒤에 수행한다. 이번 기록을 위해 앱 CI·구현·배포를 추가하지 않는다.