AI 브라우저 테스트 자동화: 에이전트가 UI를 직접 확인하게 만드는 최소 설계
AI 브라우저 테스트 자동화는 이제 선택 기능이 아니라 AI 코딩 워크플로우의 기본 안전장치가 되고 있다. 에이전트가 React 컴포넌트를 수정하고, CSS를 바꾸고, 라우트를 추가하는 일은 쉬워졌다. 하지만 브라우저에서 실제로 보이는지 확인하지 않으면 완성도가 흔들린다. 타입 체크가 통과해도 사용자는 깨진 화면을 본다.
좋은 자동화의 목표는 거창한 E2E suite를 하루 만에 만드는 것이 아니다. AI가 만든 결과물을 사람이 보기 전에 최소한의 브라우저 smoke test로 걸러내는 것이다. “페이지가 열린다”, “핵심 요소가 보인다”, “콘솔 에러가 없다”, “모바일 폭에서 CTA가 보인다” 같은 기준만으로도 실패율이 크게 줄어든다.
왜 AI 작업에는 별도 브라우저 검사가 필요한가
사람 개발자는 코드를 고친 뒤 무의식적으로 브라우저를 본다. AI 에이전트는 그렇지 않다. 명시적으로 도구와 절차를 주지 않으면 파일 수정 후 텍스트로 완료 보고를 한다. 이때 가장 많이 빠지는 것이 시각적 상태다.
예를 들어 Tailwind class 하나가 잘못되어 버튼이 배경색과 같은 색이 될 수 있다. 서버 컴포넌트와 클라이언트 컴포넌트 경계가 틀려 hydration warning이 생길 수 있다. API mock이 없어서 empty state가 영원히 보일 수 있다. 이런 문제는 코드만 읽어도 추정은 가능하지만, 실제 DOM과 console을 보는 것이 훨씬 확실하다.
AI 브라우저 테스트는 사람 QA를 대체하는 것이 아니다. PR 전에 명백한 실패를 줄이는 preflight다. 사람이 확인해야 할 화면 수를 줄이고, 리뷰어가 “일단 실행은 되나?”라는 낮은 수준의 질문에 시간을 쓰지 않게 한다.
최소 smoke test의 구성
첫 번째 항목은 route availability다. 변경한 페이지와 관련된 주요 route가 200으로 열리는지 확인한다. Next.js라면 /, /dashboard, /settings처럼 핵심 경로를 고른다. 이 단계에서 404, middleware redirect loop, runtime error를 잡는다.
두 번째 항목은 console health다. page.on('console')과 page.on('pageerror')를 수집해 error 이상을 실패로 본다. warning은 처음부터 모두 fail 처리하면 노이즈가 많을 수 있으니, hydration mismatch, failed resource, unhandled promise rejection부터 차단한다.
세 번째 항목은 core element visibility다. 페이지별로 제목, 주요 CTA, 입력폼, 리스트 컨테이너 같은 핵심 요소를 2~4개만 확인한다. selector는 brittle한 class보다 role, text, test id를 우선한다. 네 번째는 viewport check다. 모바일 390px, 데스크톱 1440px 정도에서 주요 CTA가 viewport 안에 들어오는지 본다.
에이전트에게 줄 테스트 지시문
브라우저 테스트를 AI에게 맡길 때는 “알아서 확인해줘”라고 쓰면 결과가 흔들린다. 지시문에는 범위, 명령, 실패 기준, 수정 권한을 명확히 써야 한다.
예시는 이렇다. “수정 후 npm run dev를 띄우고 Playwright smoke test를 실행한다. 확인 route는 /, /pricing, /dashboard다. console error, pageerror, 주요 CTA 미노출, 모바일 overflow는 실패다. 실패하면 원인을 한 번만 수정하고 다시 테스트한다. dependency 추가와 production config 수정은 금지한다.”
이 정도로 좁히면 에이전트가 테스트 명령을 추측하지 않고, 실패 기준도 일정해진다. 재시도 횟수도 제한해야 한다. 무한 수정 루프는 비용과 시간을 태운다. 보통 한 번 수정 후 재검사, 실패하면 로그와 함께 사람에게 넘기는 방식이 안전하다.
테스트 코드 예시 구조
도구는 Playwright, Puppeteer, Cypress 중 무엇이든 가능하다. AI 작업 preflight에는 Playwright가 적당하다. 빠르고 headless 실행이 쉽고, role 기반 selector와 screenshot 수집이 편하다.
테스트 파일은 기능별 E2E와 분리한다. 예를 들어 tests/ai-smoke.spec.ts에 핵심 route만 둔다. 각 test는 10초 안에 끝나야 한다. 외부 API가 필요한 화면은 mock이나 demo data를 사용한다. production API를 직접 호출하는 smoke test는 피한다.
결과 artifact도 단순해야 한다. 실패 route, console error, screenshot path, DOM snippet 정도면 충분하다. AI에게 전체 trace zip을 던지면 노이즈가 많다. 사람이 보기에도 한눈에 원인을 알 수 있는 요약을 만든다.
흔한 실패와 대응
가장 흔한 실패는 selector 불안정성이다. CSS class나 auto-generated id를 잡으면 작은 리팩터링에도 테스트가 깨진다. role과 accessible name을 쓰면 테스트 품질과 접근성이 같이 좋아진다.
두 번째 실패는 네트워크 의존성이다. staging API가 느리거나 외부 이미지가 막히면 AI 작업과 무관하게 테스트가 실패한다. smoke test는 가능한 한 fixture와 mock을 쓰고, 외부 리소스 실패는 별도 warning으로 분류한다.
세 번째 실패는 테스트가 너무 많아지는 것이다. AI preflight는 빠른 게 생명이다. 전체 결제 flow, 회원가입 flow, 권한 matrix를 모두 돌리면 에이전트가 작은 수정마다 오래 기다린다. 중요한 고위험 flow는 nightly나 PR gate로 분리하고, AI preflight는 얇게 유지한다.
실행 체크리스트
- AI 작업용 smoke test와 전체 E2E test를 분리한다.
- route 3
5개, 핵심 요소 24개, viewport 2개부터 시작한다. - console error, pageerror, hydration mismatch, 주요 CTA 미노출을 기본 실패 기준으로 둔다.
- selector는 role, text, test id를 우선하고 CSS class 의존을 줄인다.
- 외부 API와 production 데이터는 mock 또는 demo fixture로 대체한다.
- 에이전트 재시도는 1회로 제한하고, 실패 시 로그·screenshot 요약을 남긴다.
- smoke test는 30초 안에 끝나게 유지하고, 무거운 E2E는 별도 게이트로 둔다.
출처: Datasette Agent app_debug 공개 내용, Playwright 공식 문서, AI 코딩 에이전트 실무 운영 패턴.