테스트 데이터 팩터리와 환경 설정 (Playwright + TypeScript, 17장)
출처: Dev.to
우리 테스트에 두 종류의 상수가 스며들고 있습니다: 인라인 데이터 객체({ title, description, body, tagList })와 URL. 두 상수 모두 하나의 집이 필요합니다.
이 장에서는 데이터 팩토리와 타입이 지정된 환경 모듈이라는 하나의 집을 제공하고, Part 4를 마무리합니다.
이 장의 코드는 레포지토리에서 ch-17 태그가 붙어 있습니다:
https://github.com/aktibaba/playwright-qa-course — src/fixtures-data/article.ts와 src/utils/env.ts를 확인하세요.
데이터 팩토리
아티클을 만드는 모든 테스트가 동일한 필드를 일일이 적고 있었습니다. 팩토리는 “유효한 아티클이 어떤 모습인지”를 중앙집중화하고, 고유성을 부여하며, 테스트가 필요한 부분만 오버라이드할 수 있게 해줍니다.
// src/fixtures-data/article.ts
export interface ArticleInput {
title: string;
description: string;
body: string;
tagList: string[];
}
let seq = 0;
export function articleData(overrides: Partial<ArticleInput> = {}): ArticleInput {
seq += 1;
return {
title: `Test Article ${Date.now()}-${seq}`,
description: "Generated by the article factory",
body: "Article body for automated tests.",
tagList: [], // API에서 요구함 (Ch.13)
...overrides,
};
}
우리의 프로비저닝 유틸리티는 이제 이 팩토리를 그대로 사용합니다:
// src/utils/scenarios.ts
export async function createArticle(api, overrides: Partial<ArticleInput> = {}) {
const res = await api.post("articles", { data: { article: articleData(overrides) } });
// ...
}
이렇게 하면 테스트는 의도에 집중할 수 있습니다 — makeArticle({ tagList: ["integration"] }) — 그리고 고유한 제목, 유효한 기본값, tagList 필수 규칙은 모두 한 곳에 모여 있습니다. 아티클 구조를 한 번만 바꾸면 모든 테스트가 자동으로 따라갑니다.
왜 src/fixtures-data/ (별칭 @data)에 두고, 별도의 fixture로 만들지 않았을까요? 이유는 이것이 순수 데이터이기 때문입니다 — page도 없고, 라이프사이클도 없습니다. 팩토리는 단순 함수이고, 이를 사용하는 fixture는 설정과 정리를 담당합니다. 이를 분리하는 것은 Chapter 10에서 다룬 레이어 규칙과 동일합니다.
타입이 지정된 환경 모듈
다른 산재된 상수는 바로 URL입니다. env는 진실의 단일 출처이며, 이제 멀티 환경을 지원합니다: TEST_ENV로 목표 환경을 선택하고, WEB_URL / API_URL으로 개별 URL을 오버라이드할 수 있습니다.
// src/utils/env.ts
export type EnvName = "local" | "ci" | "staging";
const ENVIRONMENTS: Record<EnvName, { webURL: string; apiURL: string }> = {
local: { webURL: "http://localhost:3000", apiURL: "http://localhost:3001/api" },
ci: { webURL: "http://localhost:3000", apiURL: "http://localhost:3001/api" },
staging: { webURL: "https://inkwell-staging.example.com", apiURL: "https://inkwell-staging.example.com/api" },
};
const name = (process.env.TEST_ENV as EnvName) || "local";
const base = ENVIRONMENTS[name] ?? ENVIRONMENTS.local;
export const env = {
name,
webURL: process.env.WEB_URL ?? base.webURL,
apiURL: process.env.API_URL ?? base.apiURL,
} as const;
이제 같은 테스트 스위트를 어디서든 실행할 수 있습니다:
npm test # 로컬 (기본)
TEST_ENV=staging npm test # 스테이징 배포 대상으로 실행
API_URL=http://host:4000/api npm test # 일시적 오버라이드
핵심 원칙: env.ts만이 process.env를 읽습니다. 테스트, 페이지 객체, 그리고 fixture는 env를 임포트할 뿐, 환경 변수를 직접 다루지 않습니다. 이렇게 하면 설정이 한 곳에 모여 감사하기 쉬워지고, Chapter 10에서 배운 레이어 규칙이 설정에도 적용됩니다.
Part 4, 완료
통합 마일스톤이 완성되었습니다: storageState로 한 번 인증하고, API로 시드를 만든 뒤 UI에서 검증하며, 이제 깔끔한 팩토리와 환경 설정을 갖추었습니다. 테스트 스위트는 빠르고, 격리되어 있으며, 다양한 환경에서 이식 가능합니다.
다음 — Part 5: 확장, 설정 및 CI
Chapter 18 — 멀티 환경 설정에서는 방금 만든 env 모듈을 Playwright 프로젝트 시스템에 연결해, 하나의 설정 파일로 여러 환경을 대상으로 기본 URL, 재시도 정책, 메타데이터 등을 지정할 수 있게 합니다. 태그: ch-18.
함께 따라가고 있나요? 레포지토리에 ⭐️를 눌러주시고, 여러분의 테스트 데이터 팩토리가 가장 많이 생성하는 것이 무엇인지 알려 주세요.