라이브러리 제작에서 사용한 E2E Test Cypress
fetch 라이브러리의 안정성을 확보하기 위해 사용했던 Cypress에 대해 공유하고자 합니다.
다양한 테스트 방법이 있지만, 인증 관리가 필요한 이 라이브러리 테스트에 있어 Cypress를 활용한 E2E 테스트를 선택한 이유는 다음과 같습니다.
일반적으로 테스트 방법에는 다음과 같은 유형이 있습니다
- 단위 테스트: 함수나 메서드와 같은 코드의 개별적인 부분을 독립적으로 검증하는 테스트입니다. 빠른 피드백을 제공하며, 비즈니스 로직이 올바르게 동작하는지를 주로 확인합니다.
- 통합 테스트: 여러 모듈이 서로 상호작용하는 방식을 테스트하여, 시스템의 각 부분이 통합되어 제대로 작동하는지를 확인합니다. 종속성이나 모듈 간의 상호작용을 검증하기에 유용합니다.
- E2E 테스트: 실제 사용 환경을 재현하여 전체적인 사용자 흐름을 테스트합니다. UI와 API의 상호작용, 인증과 같은 사용자 경험을 통합적으로 검증하기 때문에 최종 사용자에게 가까운 방식으로 테스트할 수 있습니다.
이번 프로젝트에서는 인증 흐름을 포함한 복잡한 사용자 시나리오를 검증해야 했기 때문에, Cypress를 사용하여 E2E 테스트를 수행했습니다. Cypress를 선택한 이유는 다음과 같습니다
- 인증 흐름 자동화: Cypress는 브라우저 환경을 완벽하게 재현할 수 있어, 로그인, 토큰 발급 및 갱신, 세션 유지 등 인증이 필요한 모든 과정을 사용자처럼 자동화하여 테스트할 수 있었습니다.
- 상태 관리: Cypress는 쿠키와 로컬 스토리지와 같은 상태를 관리할 수 있어, 인증 상태에 따른 접근 제어와 세션 유지 등의 시나리오를 테스트하기에 적합했습니다.
- 실제 사용자 경험에 가까운 시나리오 구성: Cypress의 명령 체인을 통해 여러 API 호출과 토큰 갱신 과정을 순차적으로 테스트하여 실제 사용 흐름을 재현할 수 있었습니다.
Cypress 설치
먼저, Cypress를 설치하여 프로젝트에서 사용할 수 있도록 설정합니다.
npm으로 설치
yarn으로 설치
pnpm으로 설치
Cypress 설정 파일 구성 및 역할 설명
Cypress를 사용하여 E2E 테스트를 진행하면서, 저는 여러 설정 파일을 커스터마이징하여 테스트 효율성을 높였습니다. 각 파일이 어떤 역할을 하는지 설명하겠습니다.
1. command.ts: 커스텀 명령어 정의
command.ts 로그인 관련 작업을 cy.login 명령어로 만들어 테스트 전반에 쉽게 재사용할 수 있도록 했습니다.
cy.login 명령어를 통해 로그인 요청을 보내고, 성공 시 발급받은 ACCESS_TOKEN과 REFRESH_TOKEN을 환경 변수에 저장하여 이후 테스트에서 인증 상태를 유지할 수 있습니다.
2. index.ts: 타입 정의 및 전역 설정
index.ts 파일에서는 Cypress의 전역 설정을 관리하고, 커스텀 명령어에 대한 타입 정의를 추가했습니다. TypeScript는 Cypress 커스텀 명령어를 기본적으로 인식하지 않기 때문에, cy.login 명령어를 TypeScript에서도 사용할 수 있도록 타입을 선언했습니다.
3. e2e.ts: API 인스턴스 생성
e2e.ts 파일은 Cypress가 매 E2E 테스트 실행 전에 자동으로 로드하는 설정 파일입니다. 이 파일은 커스텀 명령어 등록, 글로벌 설정 및 예외 처리 등을 통해 테스트의 안정성과 편의성을 높여줍니다.
테스트 실행 전 설정
before 훅을 통한 전역 설정: 모든 테스트가 시작되기 전에 실행될 설정을 정의합니다. 예제에서는 cy.login을 호출하여 특정 계정(test1234@test.com)으로 로그인한 상태에서 테스트가 시작되도록 설정했습니다. 이를 통해 매 테스트마다 로그인을 반복할 필요 없이, 필요한 초기 설정을 한 번만 적용할 수 있습니다.
전역 예외 처리
전역 예외 처리: Cypress는 기본적으로 uncaught:exception 이벤트를 발생시키면 테스트를 중단하지만, 여기서는 모든 예외를 무시하고 테스트가 중단되지 않도록 설정했습니다
4.test.cy.ts
Cypress 테스트 구조
describedescribe는 테스트를 그룹화하는 데 사용됩니다. 테스트 모음에 대해 설명을 제공하며, 이를 통해 테스트를 논리적 단위로 구성할 수 있습니다.
itit은 단일 테스트 케이스를 정의하는 데 사용됩니다. describe 내부에 여러 개의 it을 포함하여 다양한 테스트를 실행할 수 있습니다.
expectexpect는 테스트의 예상 결과를 정의하는 Assertion입니다. 이를 통해 테스트 결과가 예상한 대로 동작하는지 확인할 수 있습니다.
먼저 Api 클래스의 인스턴스를 생성합니다. 이 인스턴스는 baseUrl, getToken, onRefreshToken과 같은 속성을 설정하여 Supabase와의 API 통신을 처리합니다. getToken은 요청 시 토큰을 가져오는 함수이고, onRefreshToken은 토큰 만료 시 새로운 토큰을 발급받는 함수입니다.
인스턴스 생성
요청 보내기
이 Api 인스턴스를 사용하여 Supabase API에 GET 요청을 보냅니다. 요청에 필요한 ACCESS_TOKEN과 apikey를 beforeRequest에서 설정하고, 성공 시 응답 데이터를 검증합니다.