10.4 Project Dependency와 Global Setup
인증, seed, environment health check 같은 선행 작업은 project dependency 또는 global setup으로 구성할 수 있습니다. 기본 선택은 일반 test처럼 trace, fixture, report를 활용할 수 있는 project dependency입니다.
Setup project
export default defineConfig({
projects: [
{
name: 'setup',
testMatch: /.*\.setup\.ts/,
},
{
name: 'chromium',
use: { ...devices['Desktop Chrome'], storageState: 'playwright/.auth/user.json' },
dependencies: ['setup'],
},
],
});
// tests/auth.setup.ts
import { test as setup, expect } from '@playwright/test';
setup('authenticate', async ({ page }) => {
await page.goto('/login.html');
await page.getByLabel('이메일').fill('student@example.com');
await page.getByRole('button', { name: '로그인' }).click();
await expect(page).toHaveURL(/dashboard/);
await page.context().storageState({ path: 'playwright/.auth/user.json' });
});
Dependency가 실패하면 이를 필요로 하는 project는 실행되지 않습니다. Setup 자체가 HTML report와 trace에 나타나므로 authentication failure를 분석하기 쉽습니다.
Global setup과 비교
| 항목 | Project dependency | Global setup |
|---|---|---|
| Report에 test로 표시 | 예 | 제한적 |
| Fixture 사용 | 예 | 직접 구성 필요 |
| Trace | 일반 test 정책 적용 | 수동 구성 |
| Project filtering | dependency 규칙 적용 | 전역 실행 |
| 적합한 용도 | login, seed, health check | runner 전역 process setup |
Worker별 account
하나의 storage state를 모든 worker가 공유하면 server-side cart, profile, quota가 충돌할 수 있습니다. Worker fixture로 account를 임대하거나 worker index 기반 namespace를 사용합니다.
const account = accounts[workerInfo.parallelIndex];
parallelIndex는 0..workers-1 범위이며 failure 뒤 worker process가 재시작돼도 같은 값을 유지합니다. 반면 workerIndex는 새 process마다 증가하므로 고정 account pool의 index로 쓰면 재시작 뒤 다른 worker와 충돌할 수 있습니다. Account pool이 worker 수보다 작으면 test가 flake하는 대신 명시적으로 실행을 제한해야 합니다.
Teardown
Setup project에 teardown project를 연결해 모든 dependent test가 끝난 뒤 환경을 정리할 수 있습니다. 하지만 실패 시 forensic evidence가 필요하다면 즉시 삭제보다 TTL cleanup이 낫습니다.
실습
- Lab login을 setup project로 분리합니다.
- Setup locator를 깨서 dependent project가 skip되는 report를 확인합니다.
- Storage state file에 어떤 cookie/local storage가 저장되는지 검토합니다.
- Auth file을
.gitignore에 추가하고 CI secret과 분리합니다.