Cypress Reference
Cypress E2E 테스트 레퍼런스
Cypress Reference 소개
Cypress 레퍼런스는 Cypress로 신뢰할 수 있는 E2E 테스트를 작성하는 데 필요한 모든 것을 다루는 실용적인 치트 시트입니다. 명령어(cy.visit, cy.get, cy.type, cy.click, cy.select, cy.scrollTo), 선택자(data-testid, cy.find, cy.first, cy.eq, cy.parent, cy.closest), 어설션(should("be.visible"), should("have.text"), should("have.length")), 인터셉트(응답 스텁, 에러 모킹, 지연 시뮬레이션), 픽스처, 커스텀 명령, 설정, 베스트프랙티스 등 8개 카테고리로 구성됩니다. 모든 항목에 실제 테스트 코드 예제가 포함되어 있습니다.
이 레퍼런스는 Cypress로 테스트 주도 개발을 도입하는 프론트엔드 개발자, QA 엔지니어, 풀스택 팀을 위해 설계되었습니다. 인터셉트 섹션은 API에 의존하는 UI를 테스트하는 팀에 특히 유용합니다. 응답 스텁, 에러 상태 모킹(statusCode: 500), 느린 네트워크 시뮬레이션(delay), 요청 별칭을 이용한 cy.wait("@alias") 대기 방법을 모두 다룹니다. 픽스처 섹션은 JSON 테스트 데이터를 로드하고 cy.intercept와 결합하여 반복 가능하고 격리된 API 모킹을 수행하는 방법을 보여줍니다.
커스텀 명령 섹션은 로그인 플로우 같은 반복 동작을 cy.login() 커스텀 명령으로 캡슐화하는 방법과 기존 명령을 재정의하는 Cypress.Commands.overwrite()를 설명합니다. 베스트프랙티스 섹션에서는 안정적인 선택자를 위한 data-testid 사용, UI 대신 API를 통한 상태 시딩, 조건부 테스트 회피, cy.session()을 이용한 로그인 세션 캐싱으로 테스트 속도를 높이는 방법 등 핵심 규범을 다룹니다.
주요 기능
- 8개 카테고리: 명령어, 선택자, 어설션, 인터셉트, 픽스처, 커스텀명령, 설정, 베스트프랙티스
- 완전한 cy.intercept API: 응답 스텁, 에러 모킹(statusCode: 500), 지연 시뮬레이션, 요청 별칭
- 주요 어설션 전체 포함: be.visible, have.text, have.value, have.class, have.length, exist, contain, have.attr
- 선택자 전략: data-testid, cy.find, cy.eq, cy.first/last, cy.parent/children, cy.closest
- cy.fixture, cy.readFile, cy.writeFile, fixture + intercept 패턴을 이용한 픽스처 기반 API 모킹
- 커스텀 명령 패턴: 로그인 플로우를 위한 Cypress.Commands.add()와 Cypress.Commands.overwrite()
- cypress.config.js 설정: 환경 변수, Cypress.env() 접근, retries 설정
- API 시딩, data-testid, cy.session() 로그인 캐싱 등 베스트프랙티스 패턴 수록
자주 묻는 질문
cy.intercept()란 무엇이고 언제 사용하나요?
cy.intercept()는 테스트 중 애플리케이션이 보내는 네트워크 요청을 가로챕니다. 응답 스텁(실제 서버 없이 가짜 데이터 반환), 에러 조건 모킹(statusCode: 500), 느린 네트워크 시뮬레이션(delay: 2000), 또는 단순히 요청 발생 여부 확인에 사용합니다. 기존 cy.route()를 대체하는 표준 방식입니다. .as("name")으로 요청에 별칭을 붙이면 cy.wait("@name")으로 요청 완료를 기다릴 수 있습니다.
CSS 선택자 대신 data-testid를 써야 하는 이유는 무엇인가요?
CSS 클래스명과 DOM 구조는 UI 개발 중 자주 변경됩니다. data-testid="submit-btn" 속성을 사용하면 애플리케이션과 테스트 사이에 안정적인 계약을 만들 수 있습니다. 사용자에게 보이지 않고, 스타일 변경에 영향을 받지 않으며, 테스트 의도를 명확하게 전달합니다. 이는 Cypress 공식 베스트프랙티스 중 하나입니다. 사용자에게 의미 있는 aria-label 같은 aria 속성도 사용할 수 있습니다.
모든 테스트에서 로그인을 반복하지 않으려면 어떻게 하나요?
가장 좋은 방법은 cy.session()입니다. 첫 번째 로그인 후 세션 상태(쿠키, localStorage, sessionStorage)를 캐시하고 이후 테스트에서 복원합니다. 또는 Cypress.Commands.add()로 cy.login() 커스텀 명령을 만들고, UI 클릭 대신 cy.request()를 통해 API로 로그인하는 방식을 사용할 수 있습니다. API 로그인이 훨씬 빠르고 안정적입니다.
cy.get()과 cy.find()의 차이는 무엇인가요?
cy.get()은 문서 루트부터 전체 페이지를 검색하고, cy.find()는 이전에 선택한 요소 내에서 검색합니다. 예를 들어 cy.get(".parent").find("li")는 .parent 내의 li 요소만 찾지만, cy.get("li")는 페이지 어디서든 모든 li 요소를 찾습니다. cy.find()를 사용하면 쿼리 범위를 특정 컨테이너로 제한하여 테스트가 더 정밀해지고 다른 변경에 강해집니다.
Cypress로 API 에러 상태를 테스트하는 방법은 무엇인가요?
cy.intercept()에 statusCode: 400, 401, 403, 500 등 에러 코드를 지정하여 에러 응답을 시뮬레이션합니다. 예를 들어 cy.intercept("GET", "/api/data", { statusCode: 500, body: { error: "Server Error" } })를 설정하면 애플리케이션이 /api/data를 요청할 때 500 에러를 받습니다. 이후 UI에 에러 메시지가 올바르게 표시되는지 어설션으로 확인할 수 있습니다. 실제 실패 서버 없이도 에러 처리 로직을 테스트할 수 있습니다.
Cypress 픽스처는 어떻게 사용하나요?
픽스처는 cypress/fixtures 디렉토리의 정적 JSON 파일입니다. cy.fixture("users.json")은 파일을 로드하고 파싱된 내용을 .then() 콜백에서 반환합니다. cy.intercept()와 함께 사용할 때는 응답 본문으로 { fixture: "users.json" }을 전달하면 픽스처 데이터를 자동으로 로드하여 반환합니다. cy.readFile()과 cy.writeFile()은 테스트 중 임의 파일을 읽고 쓸 수 있어 동적 데이터 생성에 유용합니다.
API 시딩이란 무엇이고 UI 설정보다 나은 이유는 무엇인가요?
API 시딩은 UI 클릭 대신 beforeEach에서 직접 API 호출(cy.request())로 테스트 데이터와 애플리케이션 상태를 설정하는 방법입니다. 더 빠르고 안정적이며 테스트를 UI 버그로부터 격리합니다. 예를 들어 매 테스트 전 관리자 패널에서 사용자를 생성하는 대신 cy.request("POST", "/api/users", { name: "test" })를 직접 호출합니다. Cypress 베스트프랙티스 가이드는 API 시딩을 선행 조건 설정의 기본 방식으로 권장합니다.
Cypress를 다른 환경에 맞게 설정하는 방법은 무엇인가요?
cypress.config.js(TypeScript는 cypress.config.ts)에서 baseUrl, 뷰포트 크기, 기본 타임아웃을 설정합니다. 환경별 값(API URL, 인증 정보)은 defineConfig()의 env 객체에 넣고 Cypress.env("key")로 접근합니다. CI/CD 파이프라인에서는 커맨드라인에 --env key=value를 전달하여 env 값을 재정의할 수 있습니다. retries 설정(runMode: 2, openMode: 0)을 사용하면 CI에서 불안정한 테스트를 자동으로 재시도하면서 로컬 개발 피드백에는 영향을 주지 않습니다.