11.4 Network 실패와 복구
Happy path만 mock하면 실제 장애에서 중요한 loading, retry, error message가 검증되지 않습니다. 같은 endpoint에 success, delay, malformed body, HTTP error, connection abort를 주입합니다.
Success mock
await page.route('**/api/summary', route => route.fulfill({
status: 200,
json: { source: 'mock', total: 42 },
}));
원본 response 수정
공식 API mocking example처럼 real response를 가져와 필요한 field만 보강할 수 있습니다.
await page.route('**/api/summary', async route => {
const response = await route.fetch();
const json = await response.json();
await route.fulfill({ response, json: { ...json, total: 99 } });
});
Delay, error, recovery sequence
let attempts = 0;
await page.route('**/api/summary', async route => {
attempts += 1;
if (attempts === 1) {
await new Promise(resolve => setTimeout(resolve, 500));
await route.fulfill({
status: 503,
json: { error: 'temporarily unavailable' },
});
return;
}
await route.fulfill({
status: 200,
json: { source: 'recovered', total: 3 },
});
});
await page.goto('/');
await expect(page.getByRole('alert')).toHaveText(/다시 시도/);
await page.getByRole('button', { name: '요약 새로고침' }).click();
await expect(page.getByTestId('summary')).toContainText('서버 항목');
expect(attempts).toBe(2);
첫 request만 503으로 만들고 두 번째 request에는 정상 응답을 주므로 retry 뒤 recovery assertion이 실제로 성립합니다. Test code의 raw timer는 이 예제처럼 network delay injection에만 제한적으로 사용합니다. Product readiness는 UI state assertion으로 기다립니다.
HAR replay
HAR는 여러 request의 실제 shape를 재생할 때 편리하지만 token, cookie, query parameter, response body에 민감 정보가 들어갈 수 있습니다. Commit 전 sanitize하고 update: true를 CI에서 사용하지 않습니다.
관측할 항목
- Request method, URL, essential header
- Response status와 duration
- Retry 횟수와 backoff
- Error message의 사용자 action
- Console/page error
- Trace network entry
실습
- 200 → 503 → 200 sequence를 만들어 retry UI를 검증합니다.
- JSON field를 제거해 schema drift를 재현합니다.
route.abort('connectionfailed')로 offline-like failure를 만듭니다.- Mock test와 real server test의 책임을 문서화합니다.
- HAR에서 secret을 검사하는 pre-commit rule을 설계합니다.