- Published On
테스트 라이브러리 Cypress
Cypress 소개
Cypress는 프론트엔드 개발자와 품질 보증(QA) 엔지니어에게 최적화된 최신 E2E(End-to-End) 테스트 도구입니다.
Cypress는 테스트 작성, 디버깅, 실행 과정을 모두 단순화하여 개발자가 높은 품질의 웹 애플리케이션을 제공할 수 있도록 돕습니다.
Cypress의 기본 설치 방법부터 E2E 테스트 작성 방법까지 알아보겠습니다.
Cypress 설치 및 설정
npm install --save-dev cypress
명령어를 사용하여 Cypress를 설치할 수 있습니다.
npm cypress open
명령어를 실행하면 Cypress GUI가 나타나며, 여기서 다양한 테스트를 작성하고 실행할 수 있습니다.
Cypress 파일
Cypress를 처음 실행하면 다음과 같은 기본 구성 파일들이 생성됩니다.
cypress.config.js
, cypress/support/e2e.js
, cypress/support/commands.js
, cypress/fixtures/example.json
이 항목들을 자세하게 알아보겠습니다.
cypress.config.js
이 파일은 Cypress의 기본 설정을 정의합니다.
여기에는 테스트 파일의 경로, 타임아웃 설정, 브라우저 옵션 등 다양한 설정이 포함됩니다.
예를 들어, 기본적인 cypress.config.js 파일은 다음과 같습니다:
// 이 파일은 루트 폴더에 존재합니다.
module.exports = {
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
},
baseUrl: 'http://localhost:3000',
specPattern: 'cypress/e2e/**/*.cy.{js,jsx,ts,tsx}',
},
}
support 폴더
support 폴더는 모든 E2E 테스트 파일이 로드되기 전에 실행됩니다.
e2e.js
파일에서 전역 설정이나 공통적으로 필요한 동작을 정의할 수 있습니다.
사용자 인증을 위한 설정이나 공통적으로 사용되는 커스텀 명령어 등을 여기에 정의할 수 있습니다.
commands.js
파일은 커스텀 Cypress 명령어를 정의하는 데 사용됩니다.
Cypress는 기본적으로 제공하는 명령어 외에도, 프로젝트의 필요에 따라 커스텀 명령어를 정의할 수 있습니다.
예를 들어, 아래처럼 반복되는 명령어 cy.get()을 정의할 수 있습니다.
Cypress.Commands.add("getDataTest", (dataTestSelector) => {
return cy.get(`[data-test=${dataTestSelector}]`)
});
example.json
이 파일은 테스트 데이터나 목업 데이터를 저장하는 데 사용됩니다.
예를 들어, API 테스트를 할 때 실제 데이터를 사용하는 대신 목업 데이터를 사용할 수 있습니다.
example.json은 단순한 데이터 파일이며, 아래와 같은 형식으로 불러올 수 있습니다.
desciption('fixture 불러오기',
()=>{
it('intercept 테스트', () => {
cy.intercept("POST", 'http://localhost:3000/examples', {
fixture: 'example.json'
})
cy.getDataTest('post-button').click()
})
}
)
예제 코드
describe("메인페이지 600이하 테스트", () => {
beforeEach(() => {
cy.visit("/");
});
context("폰사이즈 테스트", () => {
beforeEach(() => {
cy.viewport("iphone-x");
});
it("UI 테스트", () => {
// 로고 체크
cy.getDataTest("logo").should("be.visible");
// 모바일용 검색 버튼 체크
cy.getDataTest("search-btn").should("not.be.visible");
cy.getDataTest("smallView-search-btn").should("be.visible");
});
it("기능 테스트", () => {
const nextPageTest = (region: string, pageIndex: number) => {
cy.getDataTest(`main-${region}-${pageIndex}`).should("be.visible");
cy.getDataTest(`next-btn-${region}`).click();
};
const testRegion = (region: string) => {
const pageCount = 5;
for (let i = 0; i < pageCount; i++) {
nextPageTest(region, i);
}
cy.getDataTest(`main-${region}-0`).should("be.visible");
};
const testTheme = (theme: string) => {
cy.getDataTest(`main-${theme}-card-0`).should("be.visible");
cy.getDataTest(`main-${theme}-card-2`).should("not.be.visible");
cy.getDataTest(`main-${theme}-btn-1`).click();
cy.getDataTest(`main-${theme}-card-2`).should("be.visible");
cy.getDataTest(`main-${theme}-btn-2`).click();
cy.getDataTest(`main-${theme}-card-4`).should("be.visible");
cy.getDataTest(`main-${theme}-btn-3`).click();
cy.getDataTest(`main-${theme}-card-6`).should("be.visible");
cy.getDataTest(`main-${theme}-btn-0`).click();
cy.getDataTest(`main-${theme}-card-0`).should("be.visible");
};
// 지역 테스트
testRegion("서울");
testRegion("울산");
// 테마 테스트
testTheme("역사");
testTheme("힐링");
//축제 테스트
cy.getDataTest(`festival-card-0`).should('be.visible');
cy.getDataTest(`festival-next-btn`).click();
cy.getDataTest(`festival-card-2`).should('be.visible');
cy.getDataTest(`festival-card-0`).should('not.be.visible');
cy.getDataTest(`festival-prev-btn`).click();
cy.getDataTest(`festival-card-2`).should('not.be.visible');
});
});
context("데스크탑 화면 테스트", () => {
beforeEach(() => {
cy.viewport("macbook-16");
});
it("UI 테스트", () => {
cy.getDataTest("logo").should("be.visible");
cy.getDataTest("search-btn").should("be.visible");
cy.getDataTest("smallView-search-btn").should("not.be.visible");
});
it("기능 테스트", () => {
const nextPageTest = (region: string, pageIndex: number) => {
cy.getDataTest(`main-${region}-${pageIndex}`).should("be.visible");
cy.getDataTest(`next-btn-${region}`).click();
};
const testRegion = (region: string) => {
const pageCount = 5;
for (let i = 0; i < pageCount; i++) {
nextPageTest(region, i);
}
cy.getDataTest(`main-${region}-0`).should("be.visible");
};
const testTheme = (theme: string) => {
cy.getDataTest(`main-${theme}-card-0`).should("be.visible");
cy.getDataTest(`main-${theme}-card-2`).should("not.be.visible");
cy.getDataTest(`main-${theme}-btn-1`).click();
cy.getDataTest(`main-${theme}-card-2`).should("be.visible");
cy.getDataTest(`main-${theme}-btn-2`).click();
cy.getDataTest(`main-${theme}-card-4`).should("be.visible");
cy.getDataTest(`main-${theme}-btn-3`).click();
cy.getDataTest(`main-${theme}-card-6`).should("be.visible");
cy.getDataTest(`main-${theme}-btn-0`).click();
cy.getDataTest(`main-${theme}-card-0`).should("be.visible");
};
// 지역 테스트
testRegion("서울");
testRegion("울산");
// 테마 테스트
testTheme("역사");
testTheme("힐링");
//축제 테스트
cy.getDataTest(`festival-card-0`).should('be.visible');
cy.getDataTest(`festival-next-btn`).click();
cy.getDataTest(`festival-card-5`).should('be.visible');
cy.getDataTest(`festival-card-0`).should('not.be.visible');
cy.getDataTest(`festival-prev-btn`).click();
cy.getDataTest(`festival-card-5`).should('not.be.visible');
});
});
});
이전 포스트
JWT와 쿠키 그리고 인증 시스템 구현다음 포스트
Reflow와 Repaint의 차이점연관된 포스트 구경가기