본문으로 건너뛰기

7.3 Web server와 환경 구성

webServer는 test 전에 local application을 시작하고 지정 URL이 준비될 때까지 기다립니다.

export default defineConfig({
webServer: {
command: 'npm run dev',
url: 'http://127.0.0.1:4173/health',
reuseExistingServer: !process.env.CI,
timeout: 120_000,
},
use: {
baseURL: 'http://127.0.0.1:4173',
},
});

reuseExistingServer는 local 편의 기능입니다. CI에서는 stale server를 재사용하지 않도록 보통 false로 둡니다. Ready URL은 단순 port open보다 dependency가 준비됐음을 보여 주는 health endpoint가 좋습니다.

여러 server를 array로 정의해 frontend와 API를 함께 시작할 수 있습니다. Port 충돌, child process 종료, log capture를 확인합니다.

Hostname allowlist guard

if (process.env.BASE_URL?.includes('prod.example.com')) {
throw new Error('E2E tests must not target production');
}

Production을 향한 destructive test를 configuration 실수로 실행하지 않도록 hostname allowlist와 credential 분리를 둡니다. BaseURL과 feature flag는 report metadata에도 기록합니다.

참고: Web server

Readiness contract

webServer.url은 port open보다 application이 실제 요청을 받을 준비가 됐는지 나타내는 endpoint를 사용합니다. Database migration, seed, dependency 연결이 끝나기 전에 200을 반환하지 않게 설계합니다.

webServer: {
command: 'node server.mjs',
url: 'http://127.0.0.1:4173/health',
reuseExistingServer: !process.env.CI,
timeout: 30_000,
}

여러 server

Frontend와 mock API를 따로 띄우면 webServer 배열을 사용할 수 있습니다. Port, log prefix, shutdown을 분리해 어느 process가 실패했는지 알 수 있게 합니다.

Environment guard

const target = new URL(process.env.BASE_URL ?? 'http://127.0.0.1:4173');
if (!['127.0.0.1', 'staging.example.test'].includes(target.hostname)) {
throw new Error(`Unsafe E2E target: ${target.hostname}`);
}

실습

  1. Health endpoint를 늦춰 startup timeout을 관찰합니다.
  2. Existing local server reuse와 CI fresh server를 비교합니다.
  3. BaseURL을 report annotation으로 남깁니다.
  4. Production hostname을 configuration load 시 차단합니다.