테스트 자동화 전략
버전 0.1 (2026-08-12) · 상태 개발 착수용 초안
핵심은 하나다. 삭제 판단을 순수 함수로 떼어내 단위 테스트로 덮는다. 이 연동의 사고는 전부 거기서 나는데, 그 로직은 DB도 구글 API도 없이 시험할 수 있다.
1. 계층
| 계층 | 무엇을 | 무엇 없이 도는가 | 비중 |
|---|---|---|---|
| 단위 | 대조 판단, 제목 조립, 날짜 변환, 임계 판정 | DB·네트워크·구글 API 전부 없이 | 가장 많이 |
| 계약 | API 요청·응답 형식 | 실제 WAS 없이(골든 파일) | 중간 |
| 통합 | 실제 조회 SQL과 응답 | 데모 서비스영역 필요 | 적게 |
| E2E | 동기화 한 바퀴 | 구글 API는 가짜로 | 아주 적게 |
위로 갈수록 빠르고 안정적이다. 아래로 갈수록 느리고 잘 깨진다 — 그래서 아래는 얇게 둔다.
2. 단위 — 여기에 힘을 준다
2.1 대조 로직을 순수 함수로 떼어낸다
reconcile(expected: Event[], existing: CalendarEvent[], opts) -> Plan
Plan = { create: Event[], patch: Patch[], delete: string[], abort?: string }
- 입력이 배열 둘과 설정뿐이다. DB도 구글도 부르지 않는다.
- 실행부는
Plan을 받아 그대로 수행하기만 한다. 판단과 수행을 섞지 않는다. - 테스트 시나리오 6장(T-F-01~05)이 전부 이 함수의 단위 테스트로 재현된다.
반드시 덮을 경우
| 입력 | 기대 |
|---|---|
expected=[], existing=100건 | abort — 임계 초과 |
existing에 표식 없는 이벤트 | delete에 포함되지 않는다 |
| 창 밖 이벤트 | delete에 포함되지 않는다 |
같은 reqNo, srcStatus 20 → 30 | patch 1건, create·delete 0건 |
| 두 번 연속 적용 | 2회차 Plan이 비어 있다(멱등) |
2.2 그 밖의 순수 함수
- 제목 조립 —
[진행중]접두, 마스킹 치환, 표시명 공백일 때 - 날짜 변환 — 종일 이벤트
end.date+1일(T-E-02). 반차 시각 처리 - 기간 겹침 판정 — 달을 걸친 건(T-E-01)
- 임계 판정 — 분모가 0일 때(캘린더가 비었을 때) 나눗셈이 터지지 않는지
3. 계약 — 골든 파일
docs/api-proposal/sample-request.json·sample-response.json을 골든 파일로 고정한다.
- 응답 스키마가 바뀌면 테스트가 깨진다 → 의도한 변경이면 골든을 갱신한다
- 연동 쪽 파서는 골든 파일만으로 시험한다(WAS 불필요)
- 필수 필드 누락(
MASK_NM,CHG_DATE가 NULL인 교육 건 등)을 여기서 잡는다
4. 통합 — 데모 서비스영역
실제 SQL이 도는지 확인한다. 느리므로 적게 둔다.
- 대상: 데모
SERVAREA_ID='300' - 권한 경계(T-A-01~04)는 여기서만 진짜로 확인된다. 연동 계정의 권한을 바꿔 가며 돌린다
- 취소 시나리오(T-C-01~04)도 여기서 확인한다 — 취소승인이 원건을 40으로 바꾸는 것은
제품 프로시저의 동작이라 모의로는 검증되지 않는다
5. E2E — 구글 API는 가짜로
실제 구글 캘린더에 붙이지 않는다. 느리고, 쿼터에 걸리고, 남의 캘린더를 더럽힌다.
- 캘린더 클라이언트를 인터페이스로 두고 가짜 구현을 끼운다(메모리 맵)
- 가짜는 이벤트 목록·생성·수정·삭제만 흉내 낸다. 표식은 그대로 보관한다
- 한 바퀴 시나리오: 신규 → 승인 전이 → 취소 → 재신청 → 대량 삭제 방어
- 실제 구글 연결은 수동 확인으로 남긴다(회차마다 자동으로 돌릴 대상이 아니다)
6. 회귀 — 기준점 대조
사이트 /baseline의 기대값 JSON과 API 응답을 대조하는 스크립트를 둔다(T-Z-01).
1) GET /api/baseline → 기대값
2) POST /getTaaCalendarApiList.do (같은 조건) → 실제
3) 건수 · title · masked · 기간 비교 → 다르면 실패
- 같은 날 뽑은 것끼리 비교한다(기간 창이 오늘 기준으로 다시 계산된다)
- 이 하나가 통과하면 상태 필터·1426·기간 겹침이 함께 검증된다
- 인수 판정에 그대로 쓴다 — 사람 눈이 아니라 diff로 끝난다
7. CI 배치
| 시점 | 무엇 |
|---|---|
| 매 커밋 | 단위 + 계약 (수 초) |
| 병합 전 | 위 + E2E(가짜 구글) |
| 야간 | 위 + 통합(데모 서비스영역) + 기준점 대조 |
| 배포 전 | 전체 + 실제 구글 수동 확인 1회 |
8. 자동화하지 않는 것
정직하게 밝혀 둔다. 아래는 사람이 본다.
- 실제 구글 캘린더에서의 표시 모양(종일/시간, 색, 모바일 앱 동기화)
- 직원 구독 흐름(링크 클릭 → 추가)
- 공지문 문구가 읽히는지
- 옵션 1426 값이 업무적으로 맞는지 — 코드가 코드표에 있는지는 자동으로 보지만,
"이 휴가 종류를 감추는 것이 맞는가"는 판단이다
9. 착수 순서
- 대조 함수 시그니처부터 고정한다. 실행부보다 먼저다
- 그 함수의 단위 테스트를 T-F-01~05로 먼저 쓴다(구현 전에)
- 골든 파일 계약 테스트
- 통합·E2E는 API가 실제로 도는 뒤에
2번을 먼저 하는 까닭 — 대량 삭제 방어는 나중에 붙이면 반드시 빠진다. 정상 경로가 먼저 돌기 시작하면 "일단 되니까"로 넘어가고, 사고는 운영에서 난다.