[Test] Cypress로 E2E테스트 하기 - 설치/설정하기

GY·2022년 3월 21일
3

Test

목록 보기
1/7
post-thumbnail

E2E테스트 라이브러리 중 하나인 Cypress를 사용해보자.

공식문서부터!

❗️ 'cy' is not defined

cypress를 설치 하고 나면 다음과 같은 eslint 오류가 뜬다.

이를 해결하기 위해서 관련 플러그인을 설치하고, eslintrc에도 코드를 한 줄 추가해주었다.

cypress esling plugin

{
  "extends": [
    "react-app",
    "plugin:prettier/recommended",
    "plugin:cypress/recommended"
  ],

1. cypress 창 열기

공식문서에 적힌 대로 npx cypress open 명령어를 치면 창이 열린다.

함께 설치된 예시들을 클릭해보면 해당 사이트 창이 나오는데, 아직은 연결이 되어있지 않아 화면이 표시되지 않는다.
cy.visit()을 사용하라고 나와있는데, 공식문서를 다시 보자!


2. cypress에 프로젝트 연결하기

cy.visit() 내용 공식문서에서 보기

아래와 같은 형태로 연결해주면 된다.

잠깐, 물론 그냥 덩그러니 cy.visit()메서드만 쓰면 이런 에러가 난다.

describe나 it과 같은 다른 테스트 코드 내부에서 사용해야 한다.

cypress를 설치하면 cypress 폴더 하위에 여러 예시 파일들이 생기는데, 이 부분을 참고해보자.

3. beforeEach() 내부에서 방문하기

❗️ we include it in our beforeEach function so that it runs before each test

beforeEach메서드는 내부의 함수를 매 테스트 전에 실행시켜준다.
이 메서드 내에서 visit()메서드를 실행시켜주면 된다.


4. 본격적인 테스트 코드 작성!

액션을 취할 타겟은 직접 클릭해 선택자를 알아낼 수 있다. 그대로 복사해 붙여넣어 사용하면 된다.

describe('Nav 컴포넌트 테스트', () => {
  beforeEach(() => {
    cy.visit('http://localhost:3000');
  });

  it('지역 선택 모달창 띄우기', () => {
    cy.get('.sc-dkQkyq > :nth-child(1)').click();
  });
});


🛠 Testing Library 함께 쓰기

그런데, 한 가지 불편한 점이 있었다.

E2E 테스트의 장점은 시간을 절약할 수 있고, 계속해서 반복해야 하는 테스트 로직을 한 눈에 파악할 수 있다는 점이라고 생각하는데, 이렇게 선택자를 사용하면 어떤 부분에 대한 테스트인지 알기가 어려워 가독성이 떨어진다.

그래서 다른 사람들은 어떻게 이 테스트를 진행하는지 알아보다가, 좋은 방법을 발견했다.

바로 추가적으로 라이브러리를 사용하는 것이다.
커스텀 훅을 테스트하기 위한 방법을 찾다가 Testing Library를 사용해보기로 했었는데,
이 Testing Library를 사용해 다양한 라이브러리와 프레임워크를 테스트할 수 있었다.

그 중 Cypress를 테스트하는 라이브러리도 포함되어 있었으니, 사용해보자!
Cypress Testing Library
우선 설치 후,

npm install --save-dev cypress @testing-library/cypress

import 해 사용할 준비를 마친다.

import '@testing-library/cypress/add-commands';

간단한 사용법은 다음과 같은데, 아직 감이 오지 않아서 깃허브를 참고했다.

Cypress Testing Library Github

  1. 텍스트로 요소를 찾을 수 있다.
    코드 내에서 해당하는 텍스트를 명시해 가독성을 높일 수 있을 것 같다.
  it('findByText', () => {
    cy.findByText('Button Text 1').click().should('contain', 'Button Clicked')
  })

  it('findAllByText', () => {
    cy.findAllByText(/^Button Text \d$/)
      .should('have.length', 2)
      .click({multiple: true})
      .should('contain', 'Button Clicked')
  })

작성했던 코드를 변경해보았다.

  it('지역선택 모달창 띄우기', () => {
    cy.findByText('어디로 떠날까요?').click();
  });
});

비교해보자.

변경 전에는 어떤 요소를 테스트하는지 알기 어려웠다.

  it('지역선택 모달창 띄우기', () => {
    cy.get('.sc-dkQkyq > :nth-child(1)').click();
  });

변경 후에는 어떤 요소를 클릭하는 테스트 코드인지 보다 쉽게 알 수 있다.

  it('지역선택 모달창 띄우기', () => {
    cy.findByText('어디로 떠날까요?').click();
  });
});

이제 본격적으로 테스트를 진행해보자.


🛠 BaseURL 설정

새로운 테스트를 다시 작성하려다 보니 visit메서드에 넣을 url주소가 겹쳤다.

describe('Nav 컴포넌트 테스트', () => {
  beforeEach(() => {
    cy.visit('http://localhost:3000');
  });

  it('지역 선택 모달창 띄우기', () => {
    cy.findByText('어디로 떠날까요?').click();
  });
});

describe('상세페이지 숙박 기간 선택 테스트', () => {
  beforeEach(() => {
    cy.visit('http://localhost:3000/findstays/7');
  });

  it('체크인 날짜 선택', () => {
    //
  });
});

baseURL을 설정하면 보다 간결하게 작성할 수 있다.
cypress.json에 설정해주자.

{
  "baseUrl":"http://localhost:3000"
}

이렇게 url을 생략하고 간결하게 코드를 작성할 수 있다!

describe('Nav 컴포넌트 테스트', () => {
  beforeEach(() => {
    cy.visit('/');
  });

  it('지역 선택 모달창 띄우기', () => {
    cy.findByText('어디로 떠날까요?').click();
  });
});

describe('상세페이지 숙박 기간 선택 테스트', () => {
  beforeEach(() => {
    cy.visit('/findstay/7');
  });

  it('체크인 날짜 선택', () => {
    //
  });
});
profile
Why?에서 시작해 How를 찾는 과정을 좋아합니다. 그 고민과 성장의 과정을 꾸준히 기록하고자 합니다.

1개의 댓글

comment-user-thumbnail
2022년 4월 14일

잘보고 갑니다!!

답글 달기