본문으로 건너뛰기

4.1 BrowserContext 격리

각 test는 다른 test의 cookie, local storage, session storage에 의존하지 않아야 합니다. Playwright Test는 test마다 새 BrowserContext를 만들어 clean slate를 제공합니다.

test('starts signed out', async ({ page }) => {
await page.goto('/account');
await expect(page.getByRole('link', { name: '로그인' })).toBeVisible();
});

beforeAll에서 하나의 page를 만들고 여러 test가 순서대로 공유하면 실패가 다음 test로 전파되고 병렬 실행을 막습니다. 각 test가 필요한 상태를 직접 만들거나 fixture로 제공합니다.

격리 밖의 상태

BrowserContext만 새로 만든다고 모든 상태가 격리되는 것은 아닙니다.

  • Database row와 shared account
  • Message queue와 email inbox
  • File과 object storage
  • Third-party sandbox quota
  • Application cache와 feature flag

Parallel test는 고유한 user, order ID를 사용합니다.

test('creates an order', async ({ page }, testInfo) => {
const orderId = `order-${testInfo.testId}`;
// 이 test만 사용하는 data를 만듭니다.
});

Test 종료 시 자신이 만든 resource만 정리합니다. Shared environment 전체를 truncate하는 cleanup은 다른 worker와 충돌할 수 있습니다.

Isolation의 세 층

격리 대상구현 예
Browser statecookie, local storage, permissiontest별 BrowserContext
Server datauser, order, filetest ID/worker namespace
External servicesandbox account, quotaaccount pool, lease

Context 격리만으로 backend record 충돌은 해결되지 않습니다. Parallel worker가 같은 email이나 order를 수정하면 UI state가 격리되어도 test가 간섭합니다.

Worker namespace

const namespace = `pw-${testInfo.parallelIndex}-${testInfo.testId.slice(0, 8)}`;

Random UUID만 쓰면 collision은 줄지만 failure data를 찾기 어렵습니다. Run ID와 worker/test identity를 포함하면 cleanup과 진단이 쉬워집니다.

실습

  1. 같은 account를 두 worker가 수정해 collision을 재현합니다.
  2. Worker별 account 또는 namespace로 해결합니다.
  3. 실패 뒤 data를 즉시 지우는 경우와 TTL로 남기는 경우의 진단 trade-off를 비교합니다.
  4. Multi-user scenario에서 context별 storage를 attachment로 비교합니다.

참고: Isolation, Authentication: multiple roles