테스트 환경 설정
프로젝트에 Cypress를 설치하고 초기 구성하는 과정은 다음과 같습니다. 안정적인 패키지 다운로드를 위해 레지스트리 설정을 먼저 조정합니다.
npm config set registry https://registry.npm.taobao.org
npm install -g cnpm
cnpm install -g pnpm
설치 후 pnpm 명령어를 사용할 수 있도록 시스템 환경 변수에 npm 설치 경로를 추가합니다. 이후 프로젝트 디렉토리에서 Cypress를 개발 의존성으로 설치합니다.
pnpm add cypress --save-dev
설치 완료 후 CLI 명령어로 Cypress 테스트 러너를 실행합니다.
npx cypress open
기본 테스트 스크립트 작성
테스트 파일 spec888.cy.js를 생성하고, 웹 애플리케이션의 특정 요소가 올바르게 동작하는지 검증하는 예제를 작성합니다. 아래 코드는 로컬 서버(http://127.0.0.1:8080/test.html)에 접속하여 HTML 요소의 속성이 정상적으로 설정되는지 확인합니다.
describe('UI 상태 검증 테스트', () => {
beforeEach(() => {
cy.visit('http://127.0.0.1:8080/test.html');
});
it('초기 색상 모드가 light로 설정되어야 함', () => {
cy.get('#init').click();
cy.get('html').then(($html) => {
if (!$html.attr('color-scheme')) {
$html.attr('color-scheme', 'light');
}
cy.get('html').should('have.attr', 'color-scheme');
});
});
it('필터 초기화 시 기본 필터 적용 여부 확인', () => {
cy.get('#initFilter').click();
cy.get('html').then(($html) => {
if (!$html.attr('color-filter')) {
$html.attr('color-filter', 'normal');
}
cy.get('html').should('have.attr', 'color-filter');
});
});
it('색상 모드 변경 기능 검증', () => {
cy.get('#setColorScheme').click();
cy.get('html').then(($el) => {
if (!$el.attr('color-scheme')) {
$el.attr('color-scheme', 'dark');
}
cy.get('html').should('have.attr', 'color-scheme');
});
});
it('필터 전환 기능 동작 확인', () => {
cy.get('#setFilter').click();
cy.get('html').then(($el) => {
if (!$el.attr('color-filter')) {
$el.attr('color-filter', 'gray');
}
cy.get('html').should('have.attr', 'color-filter');
});
});
});
Cypress 선택 이유
Cypress는 브라우저 내부에서 직접 실행되며, Selenium처럼 외부 드라이버를 통한 제어 방식과 달리 더 높은 안정성과 반응 속도를 제공합니다. 또한 DOM 요소의 로딩 상태를 자동으로 감지하여 대기 시간을 최적화하므로, 명시적인 sleep 또는 wait 호출 없이 자연스럽고 신뢰성 있는 테스트를 수행할 수 있습니다.
실무에서 겪은 주요 이슈 및 해결 방법
문제 1: 외부 JavaScript 로직의 테스트 접근성 부족
HTML 페이지 내에서 독립적으로 작성된 JS 함수를 Cypress 테스트 코드에서 직접 호출하거나 import 하려는 시도가 있었으나, cy.readFile()이나 require() 등을 통해 로드해도 함수가 정의되지 않거나, addEventListener와 같은 메서드가 작동하지 않는 문제가 발생했습니다. 브라우저 컨텍스트와 Node.js 컨텍스트의 분리로 인해, Cypress 스크립트 상에서는 DOM 외부의 유틸리티 함수에 직접 접근할 수 없습니다.
해결책: Cypress 공식 문서를 참고하여 .invoke('attr', 'attributeName') 또는 .attr() 메서드를 활용해 HTML 요소의 속성을 직접 추출하는 방식으로 전환했습니다. 이를 통해 외부 JS 함수를 호출하지 않고도 UI 상태를 검증할 수 있게 되었습니다.
문제 2: GUI 기반 실행의 비효율성
개발 초기에는 cypress open 명령어로 그래픽 인터페이스를 통해 테스트를 실행했지만, 매번 런처를 초기화하는 데 30~60초가 소요되고, 각 spec 파일을 수동으로 선택해야 하는 번거로움이 있었습니다.
해결책: CI/CD 파이프라인 또는 배치 테스트 환경에서는 --headless 모드를 사용하는 것이 효율적입니다. 아래 명령어로 백그라운드에서 테스트를 실행할 수 있습니다.
npx cypress run --headless --browser chrome
이 방식은 리모트 서버에서도 자동화된 테스트 실행이 가능하며, 실행 결과는 비디오 및 스크린샷과 함께 보고서로 출력할 수 있어 유지보수성과 재현성이 뛰어납니다.