테스트 자동화에서 더 이상 어려운 점은 테스트를 작성하는 것이 아니다
요약
AI로 인해 테스트 코드 작성은 쉬워졌으나, UI 변경과 복잡한 환경에서도 유지 가능한 자동화 시스템을 구축하는 것이 새로운 과제가 되었습니다. Shadow DOM, iframe 등 복잡한 웹 구조에서도 안정적인 워크플로우를 유지하는 능력이 테스트 도구 평가의 핵심입니다.
핵심 포인트
- AI는 테스트 초안 작성을 돕지만, 유지보수 가능한 시스템 구축은 별개의 문제임
- Shadow DOM, iframe 등 복잡한 현대적 웹 구조에 대한 대응 능력이 중요함
- 단순한 기능 지원을 넘어 테스트 과정의 가시성과 이해 가능성을 평가해야 함
- 실패 시 단순 재시도가 아닌, 명확한 증거와 원인 파악이 가능한 시스템이 필요함
몇 년 전만 해도 자동화 테스트를 만드는 것이 대개 어려운 부분이었습니다.
프레임워크를 선택하고, API를 학습하며, 프로젝트 구조를 구축하고, 셀렉터(selectors)를 작성하고, 러너(runner)를 설정한 뒤, 결국 개발자 머신에서 테스트가 통과하도록 설득해야 했습니다.
그러한 작업은 여전히 존재하지만, AI가 초안 작성을 극적으로 쉽게 만들었습니다. 개발자는 흐름을 설명하기만 하면 몇 초 만에 Playwright, Selenium 또는 Cypress 코드를 얻을 수 있습니다. 노코드(no-code) 플랫폼은 여정(journey)을 기록하거나 평범한 영어 문장으로부터 편집 가능한 단계들을 생성할 수 있습니다.
병목 현상이 이동했습니다.
이제 어려운 부분은 UI가 변경되고, 팀이 성장하고, CI 환경이 더 바빠지며, 원래 테스트를 만든 사람이 다른 업무를 하고 있는 6개월 후에도 여전히 유용한 정보를 생성할 수 있는 테스트 자동화 시스템을 구축하는 것입니다.
이것은 제가 테스트 자동화를 평가하는 방식을 변화시킵니다.
저는 도구가 얼마나 빨리 성공적인 데모를 만들어낼 수 있는지보다, 데모 이후에 어떤 일이 발생하는지에 더 관심을 둡.
현대적인 웹 애플리케이션은 깨끗하고 예측 가능한 DOM 트리가 아니다
많은 테스트 자동화 예시들은 여전히 모든 버튼이 메인 문서에 보이고 모든 요소가 안정적인 식별자(identifier)를 가진 페이지를 사용합니다.
실제 애플리케이션은 더 무질서합니다.
결제 흐름(checkout flow)은 교차 출처 iframe(cross-origin iframe) 내부에 결제 양식을 포함할 수 있습니다. 디자인 시스템은 중첩된 웹 컴포넌트(web components)와 Shadow DOM을 사용할 수 있습니다. 인증, 채팅, 분석, 동의, 지원 위젯 등은 모두 제3자에 의해 각자의 일정에 따라 주입될 수 있습니다.
이것이 제가 진지한 평가가 가장 쉬운 로그인 양식이 아니라, 애플리케이션에서 가장 어려운 표면(surface)부터 시작해야 한다고 생각하는 이유입니다.
유용한 체크리스트는 How to Evaluate a Test Automation Platform for Shadow DOM, Iframes, and Embedded Third-Party Widgets에서 다루고 있습니다.
흥미로운 질문은 단순히 어떤 플랫폼이 iframe이나 Shadow DOM을 지원한다고 주장하는지 여부가 아닙니다. 핵심은 전체 워크플로우 (workflow)가 이해 가능한 상태로 유지되는가 하는 점입니다.
- 테스트가 브라우저 컨텍스트 (browser contexts)에 안정적으로 진입하고 나갈 수 있는가?
- 취약한 구현 세부 사항 (implementation details)에 의존하지 않고 컨트롤을 찾을 수 있는가?
- 어떤 문서나 컴포넌트를 검색했는지 설명해 주는가?
- 벤더 위젯 (vendor widget)이 CI에서 다르게 로드될 때 어떤 증거가 캡처되는가?
- 팀이 생성된 셀렉터 (selectors)를 역공학 (reverse-engineering) 하지 않고도 테스트를 수정할 수 있는가?
기능 표 (feature table)에 표시된 지원 기능은 실제 운영 환경 (production) 사용을 견뎌내는 지원과는 다릅니다.
증거 없는 실패는 인간에게 또 다른 작업일 뿐이다
AI 테스트 에이전트 (AI test agents)는 종종 테스트를 실행하고, 문제를 감지하고, 단계를 재시도하며, 때로는 자동으로 복구할 수 있는 시스템으로 묘사됩니다.
그것은 유용할 수 있지만, 복구 (recovery)가 이해 (understanding)와 같은 것은 아닙니다.
에이전트가 실패한 플로우 (flow)를 재시도하여 두 번째 실행이 통과했다고 가정해 봅시다. 원래의 문제가 애플리케이션 때문이었을까요, 테스트 때문이었을까요, 브라우저 환경 때문이었을까요, 데이터 때문이었을까요, 아니면 재생 (replay) 중에 내려진 다른 결정 때문이었을까요?
충분한 증거가 없다면, "재시도가 통과했다"는 것은 진단이 아닙니다.
What to Log When an AI Test Agent Replays a Failed Run and Still Can’t Explain the Failure에서 설명하는 관측 가능성 (observability) 모델은 이에 대해 생각할 수 있는 좋은 방법입니다.
유용한 실패 실행 패키지 (failed-run package)는 테스트 단계와 주변 상태를 연결해야 합니다:
- 정확한 애플리케이션 버전 및 환경;
- 피처 플래그 (feature flags) 및 사용자 권한;
- 테스트에 의해 선택된 로케이터 (locator);
- 폴백 로케이터 (fallback locators) 또는 복구 작업;
- 스크린샷, DOM 상태, 네트워크 활동 및 콘솔 에러;
- 실행 중에 생성되거나 수정된 테스트 데이터;
- 재생 (replay)이 원래 실행과 달라진 지점.
이는 특히 AI가 결정을 내릴 때 매우 중요합니다.
저는 거대한 합성 추론 (synthetic reasoning)의 벽이 필요한 것이 아닙니다. 저에게 필요한 것은 간결한 결정 경로 (decision trail)입니다: 에이전트 (agent)가 무엇을 기대했는지, 무엇을 관찰했는지, 어떤 대안을 선택했는지, 그리고 확신 수준이 어떠했는지 말입니다.
훌륭한 자동화는 단순히 무언가가 실패했다고 말하는 데 그치지 않습니다. 그것은 팀이 다음에 무엇을 해야 할지 결정하도록 도와줍니다.
프레임워크 비교에는 실제 워크플로우가 필요합니다
"어떤 프레임워크가 가장 좋은가?"라는 질문은 보통 유용한 답변을 내놓기에는 너무 광범위합니다.
워크플로우에 동적 테이블 (dynamic tables), 인라인 편집 (inline editing), 검색 필터 (search filters), 애니메이션 내비게이션 (animated navigation), API 설정 (API setup), 다중 브라우저 (multiple browsers), 또는 빈번한 UI 재설계 (UI redesigns)가 포함되느냐에 따라 답이 달라집니다.
예를 들어, Endtest vs Cypress for Testing Dynamic Tables, Search Filters, and Inline Row Actions는 일반적인 기능 비교보다 훨씬 더 구체적인 문제를 다룹니다.
그러한 구체성이 중요합니다.
동적 테이블 테스트에는 다음과 같은 과정이 필요할 수 있습니다:
- 알려진 데이터로 레코드 (record) 생성.
- 비동기 새로고침 (asynchronous refresh) 대기.
- 테이블 필터링 (filter) 또는 정렬 (sort).
- 위치에 의존하지 않고 올바른 행 (row) 찾기.
- 해당 행 내부에서 액션 (action) 트리거.
- 가시적인 결과와 백엔드 상태 (backend state)를 모두 검증.
Cypress는 코드 우선 (code-first) 팀에게 해당 워크플로우에 대한 상세한 제어권을 제공할 수 있습니다. Endtest는 QA가 다른 프레임워크 코드베이스를 소유하지 않고도 테스트 커버리지 (coverage)를 생성하고 유지 관리해야 할 때 더 매력적일 수 있습니다.
구문 (syntax)만 비교해서는 그 어떤 결론도 도달할 수 없습니다.
더 넓은 범위의 프레임워크 논의에서도 마찬가지입니다. Selenium vs Cypress in the AI Era가 흥미로운 이유는 AI가 코드를 생성하는 비용을 변화시키지만, 그 코드 뒤에 있는 소유 모델 (ownership model)을 제거하지는 않기 때문입니다.
AI는 페이지 오브젝트 (page objects), 헬퍼 (helpers), 픽스처 (fixtures), 그리고 어설션 (assertions)을 생성할 수 있습니다. 하지만 팀은 여전히 아키텍처 (architecture), 리뷰 (reviews), 의존성 (dependencies), 실패 (failures), 브라우저 인프라 (browser infrastructure), 그리고 향후의 재작성 (rewrites)에 대한 책임을 집니다.
생성된 코드를 만드는 비용은 더 저렴합니다. 하지만 운영하는 비용이 자동으로 저렴해지는 것은 아닙니다.
상태(state)를 위해서는 API를, 동작(behavior)을 위해서는 브라우저를 사용하세요
브라우저 테스트를 개선하는 가장 좋은 방법 중 하나는 설정(setup)의 모든 단계에서 브라우저를 사용하는 것을 중단하는 것입니다.
테스트 대상이 되는 동작이 '아카이브된 프로젝트가 대시보드에 올바르게 나타나는지'라고 가정해 봅시다.
사용자를 생성하고, 로그인하고, 여러 화면을 탐색하고, 프로젝트를 생성하고, 편집하고, UI를 통해 아카이브하는 과정은 테스트가 실제로 검증해야 할 지점에 도달하기도 전에 몇 분의 시간을 소모하고 수많은 실패 지점(failure points)을 추가할 수 있습니다.
API 호출은 필요한 상태(state)를 직접 생성할 수 있습니다. 그런 다음 브라우저는 사용자 경험(user experience)을 검증할 수 있습니다.
How to Combine API Calls with Playwright Tests는 이 패턴을 잘 설명합니다. 설정(setup), 정리(cleanup), 인증(authentication), 그리고 백엔드 검증(backend verification)에는 직접적인 요청(direct requests)을 사용하고, 브라우저 단계는 오직 브라우저만이 증명할 수 있는 동작(behavior)에만 집중하도록 하는 것입니다.
저는 간단한 규칙을 사용합니다:
상호작용(interaction)이 중요할 때는 UI를 사용하세요. 상태(state)가 중요할 때는 API를 사용하세요.
예외는 있습니다. 회원가입 테스트는 아마도 회원가입 인터페이스를 사용해야 할 것입니다. 양식 검증(form-validation) 테스트는 양식을 우회해서는 안 됩니다.
하지만 대부분의 대규모 테스트 스위트(suites)에는 팀이 더 깔끔한 데이터 전략을 세우지 못했다는 이유만으로 존재하는 수많은 브라우저 단계가 포함되어 있습니다.
그러한 단계들을 제거하면 속도, 안정성, 그리고 명확성을 동시에 개선하는 경우가 많습니다.
최종 페이지뿐만 아니라 릴리스 메커니즘을 테스트하세요
현대의 릴리스(releases)는 구 버전에서 신 버전으로 전환되는 단일 스위치인 경우가 드뭅니다.
기능은 먼저 직원들에게 활성화된 후, 소규모 고객 세그먼트, 그다음에는 퍼센트 단위의 롤아웃(rollout) 방식으로 활성화될 수 있습니다. 서로 다른 사용자가 동시에 서로 다른 동작을 볼 수 있습니다. 롤백(revert)은 가시적인 기능은 비활성화하면서 데이터나 백그라운드 작업(background jobs)은 그대로 남겨둘 수도 있습니다.
이는 테스트 계획이 릴리스 메커니즘(release mechanism) 자체를 다루어야 함을 의미합니다.
웹 앱에서 피처 플래그(Feature Flags), 롤아웃(Rollouts), 안전한 되돌리기(Safe Reverts)를 위한 테스트 계획을 구축하는 방법은 플래그의 양면성, 롤아웃 타겟팅(rollout targeting), 변형(variants) 간의 전환, 그리고 롤백(rollback) 동작을 모두 테스트하기 위한 유용한 모델을 제공합니다.
피처 플래그 테스트 계획은 다음과 같은 질문에 답할 수 있어야 합니다:
- 플래그가 비활성화되었을 때 기존 경험이 여전히 작동하는가?
- 새로운 경험이 의도된 모든 역할(role)과 계정 유형(account type)에서 작동하는가?
- 활성 세션(active session) 중에 플래그가 변경되면 어떤 일이 발생하는가?
- API 계약(API contracts)이 두 버전 모두와 호환되는가?
- 새로운 데이터를 손상시키지 않고 릴리스를 되돌릴(revert) 수 있는가?
- 분석(analytics) 및 감사(audit) 이벤트가 어떤 변형(variant)이 활성화되었는지 식별하는가?
상태 간의 시각적 전환(visual transition) 또한 중요합니다.
애니메이션이 적용된 경로 변경(route changes)과 CSS 뷰 전환(CSS View Transitions)은 요소가 기술적으로는 존재함에도 불구하고 로케이터(locator) 문제처럼 보이는 실패를 유발할 수 있습니다. 컨트롤이 이동 중이거나, 가려져 있거나, 일시적으로 중복되거나, 교체되고 있는 문서에 부착되어 있을 수 있기 때문입니다.
애니메이션 경로 변경 및 CSS 뷰 전환으로 인한 불안정한(Flaky) 브라우저 테스트를 줄이는 방법은 요소가 존재하기를 기다리는 것이 인터페이스가 상호작용 가능(interactive)해지기를 기다리는 것과 항상 같지는 않다는 점을 상기시켜 주는 유용한 자료입니다.
올바른 동기화 지점(synchronization point)은 임의의 지연(arbitrary delay)이 아니라, 대개 의미 있는 애플리케이션 상태(application state)여야 합니다.
CI 통합은 테스트 설계의 일부입니다
로컬에서는 작동하지만 전달 파이프라인(delivery pipeline)에 신뢰할 수 있는 결과를 제공할 수 없는 테스트는 완료된 것이 아닙니다.
CI에는 브라우저 실행을 시작하는 명령 그 이상의 것이 필요합니다. CI는 다음 사항을 알아야 합니다:
- 모든 예상된 테스트가 실제로 완료되었는지 여부
- 어떤 빌드(build)와 환경(environment)이 테스트되었는지 여부
- 실패가 기능적(functional)인 것인지 인프라적(infrastructural)인 것인지 여부
- 관련 아티팩트(artifacts)가 어디에 저장되어 있는지 여부
- 배포(deployment)를 계속해야 하는지 여부
How to Integrate Test Automation with CircleCI는 종종 간과되는 부분, 즉 원격 테스트 실행(remote test execution)을 명시적인 릴리스 게이트(release gate)로 전환하는 방법을 설명합니다.
파이프라인(pipeline)은 완료될 때까지 대기하고, 집계된 결과(aggregate result)를 가져오며, 유용한 요약(summary)을 출력하고, 증거(evidence)에 대한 링크를 보존하며, 릴리스가 차단되어야 할 때 실패하는 종료 상태(failing exit status)를 반환해야 합니다.
테스트를 트리거(triggering)하는 것은 쉽습니다.
전달 시스템(delivery system)이 그 결과를 신뢰하는 방법을 가르치는 것이 진정한 통합(integration)입니다.
브라우저 인프라에는 소유 비용(ownership cost)이 따른다
결국, 브라우저 스위트(browser suite)가 실행될 장소가 필요합니다.
그 시점에서 팀들은 종종 셀프 호스팅(self-hosted) 방식의 Selenium Grid와 BrowserStack과 같은 브라우저 클라우드(browser cloud)를 비교합니다. 서류상으로는 소프트웨어가 오픈 소스(open source)이기 때문에 셀프 호스팅 옵션이 더 저렴해 보일 수 있습니다.
누락된 항목은 바로 소유(ownership)입니다.
Selenium Grid vs BrowserStack은 이 선택을 올바르게 정의합니다: 팀이 어떤 실패 모드(failure modes)를 책임지고 싶어 하는가?
셀프 호스팅 그리드(self-hosted grid)를 사용하면 팀이 브라우저 이미지(browser images), 드라이버(drivers), 노드 상태(node health), 스케일링(scaling), 라우팅(routing), 비디오 캡처(video capture), 보안(security), 업그레이드(upgrades), 그리고 용량 계획(capacity planning)을 책임져야 할 수도 있습니다.
브라우저 클라우드를 사용하면 구독료(subscription)는 더 명확하게 드러나지만, 인프라 작업의 상당 부분이 벤더(vendor)로 넘어갑니다.
이것이 관리형 클라우드(managed cloud)가 부실한 테스트를 해결해 준다는 의미는 아닙니다. 취약한 셀렉터(selectors)와 공유된 테스트 데이터(shared test data)는 어디에서나 취약하게 남아 있습니다.
다만, 인프라가 자동화 전략의 총비용(total cost)에 포함되어야 함을 의미합니다. 프레임워크 라이선스(framework license)는 대개 그 계산에서 아주 작은 부분에 불과합니다.
수동 회귀 테스트(manual regression)를 대체하는 것은 운영 모델의 결정이다
팀들은 때때로 수동 회귀 테스트에서 자동화로 넘어가는 것을 단순한 작성 프로젝트로 취급하곤 합니다:
우리는 300개의 수동 케이스를 가지고 있다. 이를 300개의 자동화 케이스로 변환하자.
그러한 접근 방식은 기존의 프로세스를 더 비싼 형태로 재현하는 경향이 있습니다.
더 나은 질문은 무엇인가입니다. 즉, 어떤 리스크가 매 릴리스(release)마다 반복 가능한 증거를 필요로 하는지, 어떤 시나리오가 광범위한 브라우저 커버리지 (browser coverage)를 필요로 하는지, 그리고 누가 결과적으로 생성된 시스템을 현실적으로 유지 관리할 수 있는지에 대한 질문입니다.
Endtest Buyer Guide for Teams Replacing Manual Regression on Fast-Changing Frontends 기사는 중요한 점을 지적합니다. 지속적인 유지 관리 비용 (maintenance tax)이 자동화의 첫 주 비용보다 더 중요하다는 사실입니다.
이 지점이 바로 Endtest와 같은 플랫폼들이 흥미로워지는 부분입니다.
코드 우선 프레임워크 (code-first framework)는 최대한의 제어권을 원하고 이미 프레임워크를 유지 관리할 인력이 확보된 팀에게는 올바른 선택이 될 수 있습니다. 하지만 편집 가능한 테스트, 통합된 실행 (integrated execution), 셀프 힐링 (self-healing), API 단계 (API steps), 크로스 브라우저 인프라 (cross-browser infrastructure), 그리고 이해하기 쉬운 실행 증거 (run evidence)를 갖춘 플랫폼은 색다른 소유 모델 (ownership model)을 만들어낼 수 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기