- Tech
- QA
OTT에도 Playwright 자동화를
에러 로그도 없는데 화면이 비었다? 라프텔이 버그를 잡는 법
2026.09.09
1. 들어가며
어느 날, 스토어 인기 상품 랭킹이 통째로 노출되지 않는 장애가 발생했습니다. 에러 코드도 남지 않은 채 화면만 비어 있었고, 모니터링 시스템과 Unit Test 어느 쪽에서도 감지되지 않는 유형의 문제였습니다. 실제 사용자가 서비스 흐름을 끝까지 따라가야만 드러나는 버그였죠.
급한 장애를 수습한 뒤 회고를 진행하면서 한 가지 질문이 남았습니다.
“어쩌면, E2E(End-to-End) 테스트로 미리 잡을 수 있지 않았을까?"
이 경험을 계기로, 배포 과정에서 회귀(Regression)를 자동으로 검증할 수 있는 체계가 필요하다는 확신이 들었습니다. 그렇게 실제 사용자가 가장 많이 거치는 핵심 경로부터 E2E 자동화를 구축하기 시작했습니다.
하지만 OTT 서비스의 자동화는 일반적인 웹 서비스와는 조금 다른 문제였습니다. 회원 권한에 따라 화면과 기능이 달라지고, DRM 콘텐츠는 일반적인 자동화 환경에서 재생 자체가 어렵습니다. 여기에 플레이어 상태와 스트리밍 환경까지 고려해야 하다 보니, 려해야 했기 때문에, 단순히 테스트 시나리오를 늘리는 것만으로는 안정적인 자동화를 만들기 어려웠습니다.
그래서 이번 프로젝트의 목표를 테스트 개수를 늘리는 것보다 실제 서비스 환경에서 지속적으로 운영할 수 있는 자동화 구조를 만드는 것으로 잡았습니다.
어디서부터 막았나
로그인부터 결제, 재생까지 이어지는 핵심 사용자 플로우를 우선 자동화 대상으로 선정했습니다. 현재 운영 중인 자동화 규모는 아래와 같습니다.
과거에는 빠른 배포 주기에 대응하기 위해 수동 검수에 의존하는 영역이 많았고, 잦은 배포 과정에서 발생하는 회귀 이슈를 매번 동일한 깊이로 확인하는 데 한계가 있었습니다.
자동화 도입 이후에는 배포 전 검증 방식이 달라졌습니다.
현재는 서버 배포 PR이 생성되면 자동화 테스트가 함께 실행됩니다. 머지 전에 핵심 사용자 플로우를 검증하고, 하루 세 차례 실행되는 Cron 테스트를 통해 운영 환경의 회귀도 지속적으로 확인합니다. 사람이 반복적으로 수행하던 배포 전 검증의 일부를 자동화된 게이트가 담당하는 구조입니다.
2. 설계
이 구조를 지속적으로 운영하기 위해 가장 중요하게 본 것은 변경에 대한 내성이었습니다. UI 변경 하나가 테스트 전체의 유지보수 비용으로 이어지지 않도록 처음부터 역할과 책임을 분리했습니다.
흔들리지 않는 뼈대
UI는 자주 바뀝니다. 화면이 조금만 바뀌어도 테스트 전체가 같이 무너지지 않도록, Playwright 테스트의 책임을 4개 계층으로 쪼갰습니다.
핵심 원칙은 Selector는 Locator에 모으고, 최종 검증(Assertion)은 Test에서 담당하도록 책임을 분리하는 것입니다. UI가 변경되었을 때 Locator를 중심으로 수정할 수 있어 변경 영향 범위를 줄일 수 있습니다.
로그인은 한 번만
OTT 서비스는 사용자 상태에 따라 검증해야 할 경우의 수가 크게 달라집니다. 비회원부터 구독 권한, 소셜 계정, 결제 상태까지 각 조건에 따라 노출되는 화면과 사용할 수 있는 기능이 달라집니다.
매 테스트마다 로그인을 처음부터 수행하면 실행 비용이 커지기 때문에, 권한별 로그인 상태(Storage State)를 미리 생성하고 각 테스트가 필요한 인증 상태를 주입받는 방식을 사용했습니다.
인증 상태를 만드는 것보다 어려웠던 것은 병렬 실행 환경에서 상태를 서로 침범하지 않도록 만드는 것이었습니다.
여러 테스트가 동시에 실행되면서 세션과 계정 상태가 서로 영향을 주는 문제가 발생했고, Worker별 실행 환경과 계정 상태를 분리해 각 테스트가 독립적으로 실행될 수 있도록 Isolation 구조를 설계하는 데 많은 시간을 투자했습니다.
DRM 영상은 실제 Chrome으로
Playwright의 기본 Chromium 환경에서는 DRM(디지털 저작권 관리)으로 보호된 콘텐츠를 실제 사용자 환경과 동일하게 재생하기 어렵습니다. OTT 서비스에서 DRM은 필수적인 콘텐츠 보호 기술이지만, E2E 자동화에서는 플레이어의 실제 재생 경로를 검증하기 어렵게 만드는 제약이기도 했습니다.
Playwright의 기본 브라우저로 플레이어를 실행하면 DRM 단계에서 재생이 중단되었고, 결국 두 가지 선택지가 남았습니다.
DRM이 없는 테스트용 콘텐츠를 사용한다.구현은 단순하지만 실제 사용자가 거치는 DRM 재생 경로를 건너뛰게 됩니다. 자동화는 통과하지만 실제 서비스에서는 실패하는 간극이 생길 수 있습니다.
실제 Chrome을 자동화 환경에 포함한다.구현 복잡도는 높아지지만, 실제 사용자와 더 가까운 재생 환경에서 검증할 수 있습니다.
Playwright 기본 브라우저와 실제 Chrome을 함께 제어하는 구조를 구성하고, 병렬 실행에서도 Worker별 Chrome 포트와 프로필, 프로세스가 서로 충돌하지 않도록 실행 환경을 격리했습니다.
3. 운영
결과는 Slack으로, 그리고 AI 1차 진단
정기 회귀 테스트 결과는 Slack으로 공유됩니다. 통과율, 실패 건수, 테스트 환경, 소요 시간, 실행자를 한눈에 확인할 수 있도록 구성했고, 실패한 케이스가 있다면 AI가 로그와 스크린샷을 기반으로 1차 원인 분석을 수행하도록 했습니다.
하지만 AI 진단은 어디까지나 참고용으로 사용합니다. AI의 그럴싸한 답변을 먼저 보면 무심코 그 진단에 동의하게 되는 확증 편향이 생겼기 때문입니다.
그래서 저희는 판정 순서를 뒤집었습니다. AI 진단이 맞았는지 먼저 따지지 않고, 엔지니어가 실제로 코드를 고친 뒤 여러 번 재실행해도 깨지지 않을 때 '진짜 원인'으로 확정합니다. 그리고 이 확정된 정답을 AI의 1차 진단과 비교하여 데이터로 축적합니다. 사람의 주관적 인상이 아니라 시스템 결과로 AI 실제 정확도를 집계합니다.
화질 변경 기능이 반영되지 않아 테스트가 실패한 건이 있었습니다. AI는 로그를 보고 "프로덕트 버그 의심(55%)"으로 진단했지만, 실제 원인은 '네트워크 타이밍 이슈'였습니다. 가변 비트레이트(ABR) 특성상 화질 변경 명령을 즉시 받아도 이미 다운로드된 버퍼를 다 소진한 뒤에야 다음 화질이 적용되는데, 테스트 코드의 재시도(Retry) 로직이 일시적인 타이밍 차이를 기다려주지 못해 실패로 판단했던 것이었죠.
Flaky 자가격리 — 게이트 신뢰도 지키기
간헐적으로 성공과 실패를 반복하는 Flaky Test가 쌓이면 배포 게이트 자체의 신뢰도가 떨어집니다. 실패 알림이 반복될수록 "이번에도 테스트 문제겠지"라고 판단하게 되고, 결국 실제 회귀까지 놓칠 위험이 생깁니다.
적재: CI가 매 런 실패 이력을 history에 쌓습니다.
판정: 최근 N회 중 실패율이 임계치를 넘으면 격리 대상이 됩니다.
격리: 메인 배포 게이트(수행 차단 라인)에서는 제외하되, 백그라운드 실행과 추적은 유지합니다.
해제: 코드 수정 후 N회 연속 PASS를 기록하면 자동으로 격리를 해제하고 복귀시킵니다.
자가격리의 목적은 실패한 테스트를 숨기는 것이 아닙니다.
신뢰하기 어려운 테스트 하나가 전체 릴리즈를 반복적으로 막는 상황을 피하면서도, 실패 데이터를 계속 축적해 이후 충분한 근거를 가지고 디버깅할 수 있도록 게이트와 문제 분석의 시간을 분리하는 것에 가깝습니다.
운영에서 실제로 무엇을 잡았나
자동화 도입 초기에는 당장의 버그 적발 건수보다 '게이트 신뢰도'를 확보하는 데 집중했습니다. Flaky 자가격리를 통해 오탐율을 줄이면서, 개발 팀원들이 "이 게이트가 깨졌다면 100% 진짜 버그다"라고 믿고 움직일 수 있는 신뢰 환경을 만든 것이 이 시기의 가장 큰 결실이었습니다.
4. 자산화
나만이 아니라 팀이 — AI 하네스 자산화
AI가 일관된 기준으로 작업할 수 있는 실행 환경을 구축했습니다. 나 혼자만 쓰는 도구가 아니라 팀이 다시 쓸 수 있게 하는 게 목표였어요.
규칙집: 코드, 테스트 시나리오, 화면 요소 작성 규칙을 문서화하여 AI가 일관된 기준으로 코드를 작성하도록 제어합니다. 동일한 실수가 3번 반복되면 규칙으로 승격시킵니다.
역할별로 나눈 규칙·프롬프트: 코드 리뷰, 보안 점검, 테스트 설계, 디버깅 등 목적에 맞게 프롬프트를 세분화했습니다. 단, 실행과 최종 합불 판정은 AI가 아닌 결정론적인 코드(Deterministic Code)의 몫으로 남겨두었습니다.
반복 작업 단축: 실패 원인 분석이나 복잡한 Selector 찾기 등 번거로운 작업을 CLI 명령어 한 줄로 호출할 수 있게 자동화했습니다.
가드레일: 운영 배포나 비밀정보 노출 같은 위험한 작업은 시스템이 자동으로 차단합니다.
무엇을 자동화하지 않을 것인가
자동화를 하면서 오히려 또렷해진 건 반대쪽 질문이었어요. 무엇을 자동화하지 않을 것인가. AI 진단은 지금도 참고 용으로만 씁니다. 사람이 한 번 더 안 보면 못 믿겠더라고요. 자가 격리는 판단을 미뤄주는 장치일 뿐, 최종 판단과 책임은 여전히 사람에게 있습니다.
앞으로
처음 시작점이 되었던 스토어 랭킹 미노출 이슈를 계기로, 현재는 스토어 도메인이 다음 자동화 우선순위로 올라와 있습니다.
그리고 앞으로는 웹을 넘어 앱(iOS, Android, TV) 등 라프텔의 다양한 도메인으로 이 자동화 생태계를 확장해 나가려 합니다. 터진 물길을 임시로 막는 데서 시작한 여정이었지만, 이제는 물이 알아서 제 길을 안전하게 흐르도록 만드는 시스템을 향해 가고 있습니다.
source : 마녀의 여행
자동화의 목적은 사람을 대신하는 것이 아니라, 사람이 더 중요한 품질 판단에 집중할 수 있도록 만드는 것입니다. 라프텔 QA팀의 자동화는 앞으로도 그 방향으로 계속 발전해 나갈 예정입니다.