UI 자동화 테스트의 안정성과 Flaky 대응 체계

UI 자동화 테스트의 비결정성을 줄이기 위한 환경·데이터·동기화 통제와 Flaky 격리 운영 전략을 정리한다.

2026-08-14 · 최초 발행 2025-12-24

같은 테스트가 다른 결과를 내는 지점

UI 테스트가 동일한 코드와 환경에서 통과와 실패를 오간다면, 그 테스트는 Flaky 상태다. 타이밍 경쟁, 비동기 처리, UI 애니메이션, 네트워크나 백엔드의 변동, 테스트 데이터 결합, 병렬 실행 중의 자원 경합이 대표적인 원인이다.

안정적인 자동화는 입력·환경·데이터·시간을 통제하고, 실행 상태를 관찰할 수 있게 만드는 데서 출발한다. 설계·데이터·동기화로 문제를 예방하는 층과 리런·격리·관찰성으로 실패를 통제하는 층이 함께 있어야 재현성과 예측 가능성을 확보할 수 있다.

실행 환경과 데이터의 흔들림 줄이기

브라우저·드라이버·OS 버전을 고정하고 컨테이너 기반의 격리 실행을 적용한다. 병렬 샤딩 환경에서는 CPU·메모리·세션 자원 상한도 함께 설정한다. 네트워크, 클록, 랜덤 시드를 통제하고 애니메이션과 전환 효과를 비활성화하면 시각적 변동도 줄일 수 있다.

테스트 데이터는 픽스처와 시드 스크립트가 멱등적으로 동작해야 한다. 트랜잭션 단위 롤백이나 임시 스키마·테넌트를 활용하고, 테스트마다 네임스페이스와 고유 키를 둬 데이터 충돌을 막는다. 외부 의존성은 계약 기반 모킹이나 기록-재생 방식으로 분리한다.

시간 대신 상태를 기다리는 테스트

셀렉터는 CSS나 XPath의 취약한 패턴보다 data-test-id와 역할(Role)을 기준으로 잡는 편이 안정적이다. 고정 시간의 sleep은 피하고 이벤트나 상태를 기준으로 explicit wait를 사용한다.

대기 조건은 네트워크 정착(network idle), 애니메이션 종료, DOM 안정 신호처럼 실제 화면 상태와 연결돼야 한다. 이렇게 하면 화면이 준비되지 않은 상태에서 다음 동작을 수행하는 일을 줄일 수 있다.

실패를 분류하고 격리하는 운영 방식

실패한 테스트는 제한적으로 리런한다. 예를 들어 x2 리런 뒤 최근 N회 중 실패율을 기준으로 안정성 점수를 산출할 수 있다. 임계치를 넘는 테스트에는 Quarantine 라벨을 부여하고 게이트 예외로 처리한다.

원인·환경·해시를 남기는 테스트 이력 저장소를 두면 통계적 군집화로 공통 원인을 찾을 수 있다. Triage SLA와 소유자(Owner)를 지정하면 불안정 테스트가 장기간 방치되는 일을 줄일 수 있다.

실행마다 비디오, 스크린샷, 콘솔·네트워크 로그, 트레이스를 수집하고, 실패 시 아티팩트를 첨부한 이슈를 자동 생성한다. 대시보드에서는 불안정도, 리런률, MTTR을 추적한다. 게이트는 신규 실패를 차단하고 Flaky 테스트는 경고로 다루는 방식으로 운영할 수 있다.

제품 조건에 따라 달라지는 대응

PR 게이트에서는 PR 트리거 뒤 테스트 계획과 샤딩을 만들고, 컨테이너에서 조건 기반 대기 중심의 테스트를 수행한다. 실패 시 제한적 리런과 Flaky 격리를 거쳐 결과를 집계한다. 브라우저 컨텍스트 격리, 테스트 데이터 트랜잭션 롤백, 네트워크 모킹이 비결정성 제거에 쓰인다.

가격과 재고가 실시간으로 달라지는 커머스 웹은 계약 기반 API 모킹과 시점이 고정된 재고·가격 픽스처가 필요하다. UI는 data-test-id로 선택하고 가격 표시 업데이트 이벤트를 기다린다. 비동기 가격 반영이 늦어지면 지수 백오프 대기를 적용하고, 타임아웃 뒤 진단 로그를 수집한다.

Appium 기반 모바일 앱에서는 애니메이션과 전환을 끄고, 에뮬레이터 성능과 네트워크 링크 컨디셔닝을 고정한다. IdlingResource나 상태 폴링으로 화면 안정 상태를 감지하며, 테스트 사이에는 앱 상태를 초기화하고 사용자 세션을 격리한다.

iframe과 팝업이 많은 레거시 ERP는 윈도우 핸들과 프레임 전환 유틸리티를 공통화하고 팝업 준비 완료 이벤트를 기다린다. 파일 다운로드와 인쇄처럼 OS에 의존하는 단계는 샌드박스 드라이버, 가짜 프린터, 가상 FS로 결정성을 확보한다.

안정성 전략의 선택 기준

전략 성능 확장성 일관성 안정성 운영 편의
조건 기반 대기(이벤트/상태) 보통 우수 우수 우수 우수
네트워크 모킹/계약 테스트 우수 우수 우수 우수 보통
테스트 데이터 트랜잭션/픽스처 보통 우수 우수 우수 보통
제한적 재시도+Quarantine 보통 우수 보통 우수 우수
안정적 셀렉터(data-test-id) 우수 우수 우수 우수 우수
컨테이너·브라우저 버전 고정 보통 우수 우수 우수 보통

성능은 실행 시간, 확장성은 병렬성과 자원 효율, 일관성은 결정성, 안정성은 실패 억제, 운영 편의는 도입과 유지보수 난이도를 기준으로 판단한다.

PR 게이트에서 결과가 게시되기까지

테스트 계획 생성트랜잭션 시작세션 생성액션 실행조건 판정아니오재시도 판정아니오실패 판정아니오안정성 판정Flaky진성 실패트랜잭션 종료종료결과 게시결과 게시결과 게시입력 단계: PR 트리거 수신환경 프로비저닝(컨테이너,브라우저 버전 고정)테스트 데이터 준비(픽스처,시드, 시간 고정)브라우저 세션 생성(샌드박스,쿠키 격리)UI 동작 실행(조건 기반 대기,data-test-id)조건 판정어설션 수행(계약/상태/시각적)지수 백오프 재시도(N<=2)재시도 소진 여부실패 기록 아티팩트수집(스크린샷/트레이스)어설션 실패 여부리런 수행(x2)로그·트레이스 수집이력 기반 Flaky 판정(임계치 =2/3)격리(Quarantine) 지정알림버그 리포트 생성(JIRA)자원 정리 메트릭 전송대시보드 집계

개선 순서와 측정 지표

우선 안정적 셀렉터(data-test-id)로 전환하고 애니메이션을 비활성화한 뒤 조건 기반 대기를 도입한다. 이어서 멱등 픽스처와 트랜잭션 롤백, 네트워크 모킹과 계약 테스트를 적용한다. 이후 실패 리런, Flaky 점수, 격리 운영을 정착시키고 대시보드·알림·Triage SLA를 마련한다. 마지막으로 컨테이너 격리와 브라우저 버전 고정, 병렬 샤딩 최적화, 비용 관리를 다룬다.

Flaky 비율은 1530%에서 46주 내 23% 이하, 리런률은 40%에서 10% 이하를 목표로 줄일 수 있다. 사이클 타임은 2035% 단축하고 인프라 재실행 비용은 25% 절감한다. 불안정 테스트의 MTTR은 3일에서 1일로 줄이며, 개발자 신뢰도와 탈락 결함(escaped defects), 배포 중단 건수도 함께 개선 대상으로 둔다. 탈락 결함은 10~20% 감소를 목표로 한다.

UI 자동화Flaky 테스트테스트 안정성테스트 데이터CI/CD