Published On

테스트 라이브러리 Cypress


Cypress 공식문서

Cpyress 유튜브 강의

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 파일은 다음과 같습니다:

cypress.config.jsjavascript
// 이 파일은 루트 폴더에 존재합니다.
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/support/commands.jsjavascript
Cypress.Commands.add("getDataTest", (dataTestSelector) => {
  return cy.get(`[data-test=${dataTestSelector}]`)
});

example.json

이 파일은 테스트 데이터나 목업 데이터를 저장하는 데 사용됩니다.

예를 들어, API 테스트를 할 때 실제 데이터를 사용하는 대신 목업 데이터를 사용할 수 있습니다.

example.json은 단순한 데이터 파일이며, 아래와 같은 형식으로 불러올 수 있습니다.

cypress/e2e/xx.cy.jsjavascript
desciption('fixture 불러오기',
  ()=>{
    it('intercept 테스트', () => {
      cy.intercept("POST", 'http://localhost:3000/examples', {
          fixture: 'example.json'
      })
      cy.getDataTest('post-button').click()
    })
  }
)

예제 코드

cypress/e2e/mainPage/test.cy.tsjavascript
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');
    });
  });
});