E2E QA Automation
Summary
반복되던 기본 기능 검수를 E2E로 자동화하고, PR별 k3s 환경을 구축해 테스트 서버 배포 전에 변경 사항을 검증하도록 했습니다.
- Role
- QA 자동화 단독 구축과 운영 (시나리오 설계, CI와 PR별 k3s 환경 구축)
- Outcome
- 사내 첫 E2E 자동화 기반 구축, PR별 사전 검증 도입
문제 정의
반복 검수와 도구 전환에 묶여 있던 QA
입사 초반에는 저를 포함한 PO 3명이 릴리즈마다 1~2주씩 QA를 나누어 맡았습니다. 기본 동작을 반복해서 확인하느라 신규 기능의 정책과 예외를 살필 시간이 부족했습니다. 기능 간 의존성을 모두 파악하기 어려워, 작은 변경이 핵심 기능에 영향을 줄 위험도 있었습니다.
당시 테스트 케이스(TC)는 Google Sheets에서, 발견한 버그의 티켓 생성과 관리는 Jira에서 진행했습니다. 검수 중 두 도구를 반복해서 오가야 했고, 양쪽 문서를 수정하며 내용과 진행 상태를 일치시키는 일도 별도로 필요했습니다.
개선의 시작
검수 기록과 버그 상태를 하나로 통합
Google Sheets에서 버그를 작성하면 Jira 티켓이 자동 생성되고, Jira의 수정 상태가 시트에 동기화되도록 연결했습니다. 검수 항목과 버그 처리 상태를 한곳에서 확인하고 관리할 수 있게 됐습니다.
남아 있던 한계
기록을 연결해도 남아 있던 반복 검수
다만 기록 관리가 편해져도 다음 릴리즈에서 같은 기본 기능을 다시 확인하는 일은 남아 있었습니다.
기존 TC와 과거 버그, 연관 업무를 기준으로 반복되는 기본 동작을 자동화하고, 새로운 정책과 복잡한 예외는 직접 검수하도록 범위를 나눴습니다. 검증 단위는 계약 생성부터 수거 수행과 청구까지 이어지는 업무 흐름으로 잡았습니다. 한 화면의 정상 동작만으로 다음 업무까지 올바르게 이어지는지 판단하기는 어려웠기 때문입니다.
아이디어 구체화
반복되는 기본 기능 검수를 E2E로 자동화
반복되는 기본 기능 검수에 쓰는 시간을 줄여야 신규 기능의 정책과 예외를 더 살필 수 있었습니다. 릴리즈마다 같은 업무 흐름을 다시 검증할 수 있도록 E2E 테스트 자동화를 시작했습니다.
당시 공개된 Playwright MCP를 Cursor에 연결하면 실제 브라우저를 조작하고 화면을 확인하면서 테스트 코드를 작성할 수 있었습니다. 초기 테스트 기반을 빠르게 구축할 수 있다는 점에서 이 방식을 선택했고, Playwright와 TypeScript로 테스트 코드와 실행 기반을 처음부터 만들었습니다.
관리자 웹(Admin)에서 계약과 스케줄을 만들고 드라이버 앱(Driver)에서 수거를 수행한 뒤, 다시 Admin에서 수행 이력과 청구를 확인하도록 연결했습니다. 역할별 로그인 상태를 분리하고, 프로젝트 의존성과 teardown으로 준비부터 수행, 검증, 정리까지 순서를 구성했습니다.
청구 검증에서는 계약 조건과 작업량으로 예상 금액을 별도로 계산해 공급가액과 부가세, 총액을 대조했습니다. 화면의 성공 알림에 더해 API로 저장된 상태와 금액도 다시 확인했습니다.
처음에는 기존 테스트 서버의 데이터를 사용했지만, 데이터가 바뀌면 기능에 문제가 없어도 테스트가 실패할 수 있었습니다. 실행마다 필요한 계약과 스케줄을 새로 만들고 식별자를 기록해 후속 테스트에 전달했습니다. 실행이 끝나거나 중간에 실패했을 때도 생성한 데이터를 정리하도록 해, 기존 데이터의 상태가 결과에 미치는 영향을 줄였습니다.
검증 방식의 확장
PR에서 검증하고 개발자의 수정으로 이어지는 흐름
E2E로 반복 검수는 줄었지만, 테스트 서버에 병합하고 배포한 뒤에야 변경 사항을 확인할 수 있었습니다. 여러 개발자의 변경이 함께 반영되면 어느 작업이 기존 기능에 영향을 줬는지 구분하기도 어려웠습니다.
변경 사항을 PR별 환경에서 독립적으로 검증하고 결과를 해당 PR에 남기도록 했습니다. 개발자가 자신의 변경과 실패 지점을 대조해, 테스트 서버 배포 전에 문제를 확인하고 수정할 수 있게 하려는 선택이었습니다.
GitHub Actions에서 Frontend와 Backend를 빌드하고, 사내에 구축한 k3s 클러스터에 Helm으로 Frontend, Backend, DB를 배포했습니다. PR과 실행별로 namespace와 DB를 분리하고, Playwright가 해당 환경을 검증하도록 연결해 다른 PR의 변경과 데이터가 섞이지 않도록 했습니다.
브랜치 이름으로 빌드하면 실행 도중 새 커밋이 올라왔을 때, 처음 검증하려던 코드와 다른 버전이 사용될 수 있었습니다. 그래서 테스트를 시작할 때마다 검증할 Frontend와 Backend 커밋을 지정하고, 해당 실행에서는 지정한 코드로 빌드하고 테스트하도록 했습니다. 이미지와 DB 스냅샷에도 실행별 태그를 붙여, 결과가 어떤 코드와 조건에서 나온 것인지 확인할 수 있게 했습니다.
모니터링 강화
실행 상태와 실패 원인을 확인할 수 있도록
테스트가 끝날 때까지 진행 상황이 보이지 않으면 실행이 오래 걸리는지, 중간에 멈춘 것인지 구분하기 어려웠습니다. 30초마다 테스트 중인 플랫폼과 실행 단계, 경과 시간, 완료한 테스트 수와 재시도 상태를 CI 로그에 출력하도록 했습니다.
실패했을 때는 제품의 결함과 검증 환경의 문제를 구분할 수 있도록 Playwright 리포트와 Backend 로그, Pod와 Kubernetes 이벤트, Helm 상태를 함께 수집했습니다. 자료는 GitHub Actions의 artifact로 남기고, 복사가 끝날 때까지 Pod를 유지했습니다. 실패한 환경도 일정 시간 보존해 실행이 끝난 뒤에도 원인을 확인할 수 있게 했습니다.
PR별 검증 결과는 상태와 댓글로, 테스트 서버 실행 결과는 Slack으로 공유했습니다. Slack에는 플랫폼별 통과와 실패 건수, 소요 시간과 실행 링크를 담고, 실패한 테스트와 오류 내용은 스레드로 전달했습니다. 개발자가 실패 지점과 자신의 변경을 대조해 구현 오류를 수정하거나, 의도한 변경에 맞춰 테스트의 기대 결과를 갱신할 수 있게 했습니다.
결과
처음 세운 자동화 기반, 달라진 QA 방식
사내 첫 QA 자동화 기반을 0→1로 구축했습니다. 테스트 커버리지는 88.2%이며, 기본 기능 E2E는 약 1시간에 실행됩니다. 같은 화면을 수기로 반복 확인하던 시간을 줄이고, 신규 기능과 변경 사항의 정책, 예외, 연관 업무에 미치는 영향을 살피는 데 시간을 쓸 수 있게 됐습니다.
E2E 적용 전후의 정규 배포를 비교하면 QA 대상 티켓은 712건에서 992건으로 늘었습니다. 하루 평균 검증량도 22.3건에서 29.2건으로 약 31% 증가했습니다.
| 지표 | E2E 테스트 적용 전 | E2E 테스트 적용 후 |
|---|---|---|
| 검증 티켓 | 712건 | 992건 |
| 하루 평균 검증량 (티켓/일) | 22.3건/일 | 29.2건/일 (약 31% 증가) |
| 배포 후 버그 비율 | 7.0% (50건 / 712건) | 3.9% (39건 / 992건) |
검증량이 늘어나는 동안 배포 후 버그 비율은 7.0%에서 3.9%로 낮아졌습니다. 기본 기능은 E2E로 반복 검증하고, 신규 기능의 정책과 예외는 직접 검수했습니다. QA 중 발견한 버그는 Google Sheets와 Jira로 개발자의 수정 상태를 추적하고, 수정된 뒤 다시 검증했습니다.
입사 초기에는 PO 3명이 릴리즈마다 1~2주 동안 QA를 나누어 맡았습니다. QA 자동화 기반을 구축한 뒤에는 릴리즈 QA를 혼자 맡게 됐고, 현재는 평균 약 3일 만에 검수를 마칩니다. 기본 기능은 E2E로 반복 검증하고, 신규 기능과 변경 사항은 RAG로 관련 정책과 코드를 대조하며 검증 범위를 정하고 있습니다.
관련 정책과 코드 조회를 검증에 연결한 과정은 RAG Knowledge Base에서 이어집니다.