본문으로 건너뛰기

2.3 Assertion과 timeout

Web-first assertion은 locator를 반복 평가해 timeout 안에 기대 상태가 되는지 확인합니다.

await expect(page.getByTestId('status')).toHaveText('완료');
await expect(page).toHaveURL(/\/orders\/\d+$/);
await expect(page.getByRole('listitem')).toHaveCount(3);

일반 값 assertion은 자동 retry하지 않습니다.

expect(response.status()).toBe(200);

임의 callback이나 외부 system을 polling할 때는 expect.poll을 사용할 수 있습니다.

await expect.poll(async () => {
const response = await page.request.get('/api/status');
return response.status();
}).toBe(200);

Timeout 계층

  • Test timeout: fixture, hook과 test 전체 실행
  • Expect timeout: retrying assertion
  • Action timeout: click, fill 같은 action
  • Navigation timeout: navigation 계열

가장 상위 timeout만 늘리면 locator ambiguity, 느린 backend, 잘못된 state를 늦게 발견합니다. Error의 call log와 trace에서 무엇을 기다렸는지 확인합니다.

toBeVisible()만 반복하기보다 사용자에게 중요한 text, value, URL, count를 검증합니다. 단순 존재는 잘못된 data를 놓칠 수 있습니다.

참고: Assertions, Timeouts

Assertion 선택 기준

await expect(page).toHaveURL(/dashboard/);
await expect(page.getByRole('heading')).toHaveText('Dashboard');
await expect(page.getByRole('alert')).toContainText('저장했습니다');
await expect(page.getByLabel('이메일')).toHaveValue('a@example.com');
await expect(response).toBeOK();

DOM property를 직접 꺼내 generic assertion하기 전에 locator/page/API response 전용 matcher가 있는지 확인합니다.

Soft assertion

await expect.soft(summary).toContainText('총 3개');
await expect.soft(status).toHaveText('정상');
expect(test.info().errors).toHaveLength(0);

한 화면의 여러 진단 결과를 모을 때 유용하지만, 핵심 precondition까지 soft로 만들면 이후 action이 무의미해질 수 있습니다.

Timeout budget 계층

종류의미
Test timeoutsetup, action, assertion을 포함한 test 전체 budget
Expect timeoutweb-first assertion retry budget
Action timeoutclick/fill 같은 action budget
Navigation timeoutnavigation 관련 budget
Web server timeouttest 시작 전 server readiness budget

실습

  1. Expect timeout만 짧게 만들어 assertion failure를 관찰합니다.
  2. Test timeout을 늘리지 않고 느린 setup의 원인을 줄입니다.
  3. 여러 진단 항목을 soft assertion하고 마지막에 errors를 확인합니다.
  4. expect.poll()이 필요한 외부 상태 사례를 설계합니다.