개념
왜 대기가 필요한가
화면은 즉시 바뀌지 않는다. 버튼을 클릭한 뒤 서버 응답을 기다리거나, 애니메이션이 끝나야 다음 요소가 나타나는 경우가 많다. 모듈 10(레슨 4)에서 배운 비결정적 요소 중 "외부 API 응답 시간"이 UI 자동화에서는 항상 마주치는 현실이다.
나쁜 방법 — 고정 시간 대기(sleep)
await page.click("#submit")
await page.waitForTimeout(3000) // 무조건 3초 기다림
await expect(page.getByText("완료")).toBeVisible()이 방법의 문제는 두 가지다.
- 너무 짧으면: 서버 응답이 3초보다 오래 걸리는 순간(네트워크가 느려질 때) 테스트가 실패한다 — 모듈 7(레슨 3)에서 배운 플래키 테스트의 전형적인 원인
- 너무 길면: 실제로는 0.5초 만에 끝나는데도 항상 3초를 기다리므로, 테스트 전체 실행 시간이 불필요하게 길어진다
좋은 방법 — 조건이 충족될 때까지 기다리기
레슨 2에서 언급한 Playwright의 자동 대기가 바로 이 방식이다.
click()이나 fill() 같은 동작은 그 요소가 화면에 나타나고
조작 가능해질 때까지 자동으로 기다린 뒤 실행된다.
await page.getByRole("button", { name: "제출" }).click()
// 이 버튼이 나타날 때까지 자동으로 기다린 뒤 클릭한다명시적으로 "이 조건이 충족될 때까지 기다려라"라고 표현할 수도 있다.
await expect(page.getByText("완료")).toBeVisible()
// "완료"라는 텍스트가 보일 때까지 기다렸다가 확인한다(고정 시간이 아니라 조건 기반)고정 대기와 조건 대기의 차이
고정 대기(sleep): "무조건 3초 기다려라" — 얼마나 걸릴지 몰라도 항상 같은 시간
조건 대기: "이 조건이 참이 될 때까지 기다려라" — 빠르면 빨리, 느리면 늦게 끝남조건 대기는 최소한의 시간만 기다리면서도, 실제로 필요한 만큼은 충분히 기다린다는 점에서 고정 대기보다 항상 우월하다.
그래도 명시적 대기가 필요한 경우
자동 대기로 대부분의 상황은 해결되지만, 다음처럼 특수한 경우엔 직접 조건을 지정해야 할 수 있다.
// 특정 네트워크 요청이 완료될 때까지 기다리기
await page.waitForResponse(response => response.url().includes("/api/orders"))
// 특정 요소가 사라질 때까지 기다리기(예: 로딩 스피너)
await expect(page.getByTestId("loading-spinner")).toBeHidden()로딩 스피너가 사라지는 것을 기다리는 패턴은 실무에서 특히 자주 쓰인다 — "스피너가 있는 동안은 아직 준비가 안 됐다"는 신호를 직접 활용하는 것이다.
대기 전략과 플래키 테스트의 관계
모듈 7(레슨 3)과 모듈 10(레슨 4)에서 배운 플래키 테스트의 상당수가 UI 자동화에서는 부적절한 대기 전략이 원인이다. "가끔 실패하는 테스트"를 발견하면, 가장 먼저 의심해야 할 곳 중 하나가 이 부분이다.
실무에서 왜 필요한가
"CI에서만 가끔 실패하는데 로컬에서는 항상 통과한다"는 증상은, CI 서버가 로컬보다 느려서 고정 대기 시간이 부족했던 경우가 흔하다. 대기 전략의 원리를 이해하는 QA는 이런 실패를 "환경 탓"으로 넘기지 않고, 코드 수준에서 "이 대기가 조건 기반인지 고정 시간 기반인지"를 먼저 확인해 근본 원인을 찾을 수 있다.
실습 과제
과제 1 — 나쁜 대기 코드 고치기 (10분)
다음 코드를 조건 기반 대기로 고쳐 쓴다.
await page.click("#addToCart")
await page.waitForTimeout(2000)
const count = await page.textContent(".cart-count")과제 2 — 플래키 원인 진단하기 (10분)
"결제 완료 버튼을 클릭한 직후 바로 다음 화면 요소를 확인하는 테스트가 로컬에서는 항상 통과하지만 CI에서는 가끔 실패한다"는 제보를 받았다. 대기 전략 관점에서 어떤 코드를 먼저 의심해봐야 할지 적는다.
자가 체크리스트
- 고정 시간 대기(sleep)의 두 가지 문제(너무 짧음/너무 김)를 설명할 수 있다
- 조건 기반 대기가 고정 대기보다 나은 이유를 설명할 수 있다
- Playwright의 자동 대기가 어떤 상황을 처리해주는지 설명할 수 있다
- 로딩 스피너가 사라지는 것을 기다리는 패턴을 활용할 수 있다
흔한 실수
- 테스트가 가끔 실패하면 대기 시간을 무조건 늘려서 임시방편으로 땜질한다. 근본 원인(조건 기반으로 안 바꾼 것)을 고치지 않으면 같은 문제가 다른 형태로 재발한다.
- 자동 대기가 모든 걸 해결해준다고 믿고 특수한 경우(특정 API 응답 대기 등)도 신경 쓰지 않는다. 일부 상황은 여전히 명시적 대기가 필요하다.
- CI에서만 실패하는 테스트를 "CI가 느려서 그렇다"고만 치부하고 코드는 들여다보지 않는다. 느린 환경에서 고정 대기의 허점이 먼저 드러나는 경우가 많다.
참고 자료
- Playwright 공식 문서 — Auto-waiting — 자동 대기 메커니즘의 공식 설명
- Martin Fowler — Eradicating Non-Determinism in Tests — 모듈 10 레슨 4와 동일한 참고 자료, 대기 전략과 직결된 내용