Notice
Recent Posts
Recent Comments
Link
관리 메뉴

윤일무이

[Test Code] Cypress로 테스트 하기 본문

⚛️ React/📜 Test Code

[Test Code] Cypress로 테스트 하기

썸머몽 2024. 7. 2. 01:57
728x90

Cypress

 

Testing Frameworks for Javascript | Write, Run, Debug | Cypress

Simplify front-end testing with Cypress' open-source app. Explore our versatile testing frameworks for browser-based applications and components.

www.cypress.io

 

최신 웹 애플리케이션에 대한 E2E 테스트를 쉽게 생성하고, 시각적으로 디버그하고, 지속적 통합 빌드를 통해 자동으로 실행할 수 있는 테스트 도구

 

Cypress 설치 및 환경 설정

npm install --save-dev cypress

 

// package.json

"cypress": "npx cypress open"

 

 

여기서 E2E Testing을 선택해준다.

Build and test the entire experience of your application
from end-to-end to ensure each flow matches your expectations.
처음부터 끝까지 애플리케이션의 전체 경험을 구축하고 테스트 해 각 흐름이 기대에 부합하는지 테스트해보세요.

 

 

Chrome으로 시작하면 Configuration 파일을 자동으로 만들어준다.

cypress.config.ts, example.json, commands.ts, e2e.ts가 생성된다.

이후에 뜨는 창에서 Scaffold example spaces를 클릭하면 테스트할 예시 파일들이 생성된다.

 

VSC에도 이렇게 예제 파일들이 잘 생성된 걸 볼 수 있다.

 

 

파일을 클릭하면 위와 같이 테스트들이 실제 유저 화면처럼 보여지면서 진행된다.

 

Cypress 성공 케이스 작성하기

자동으로 설치되는 기존 예제 파일들을 지우고 e2e/1-login/login.cy.js라는 파일을 만들어준다.

jest 때와 마찬가지로 로그인 페이지에서 로그인이 정상적으로 이루어지는지를 테스트하려고 한다.

 

(+ cypress GUI에서 New Spec를 눌러서 생성하는 방법도 있다.)

 

테스트 설정 전에 계속 visit를 할 수 없다는 에러가 떠서 커뮤니티를 확인해봤는데 cypress.config.ts에 baseUrl을 작성해줘야하는 이슈가 있었다. 어려운 것은 아니니 바로 서버 url을 적어주면 된다.

import { defineConfig } from 'cypress';

export default defineConfig({
  e2e: {
    baseUrl: 'http://localhost:5173',
    setupNodeEvents(on, config) {
      // implement node event listeners here
    },
  },
});

 

 

 

Table of Contents | Cypress Documentation

Commands

docs.cypress.io

 

강의에서 사용한 명령어나 어설션을 비롯해 다양한 명령어들을 알아보고 싶다면 공식 문서를 참조하면 좋다.

강의에서 사용한 명령어나 자주 사용되는 명령어들을 간단하게 정리했다. 

   
cy.get(selector) 지정된 CSS 셀렉터를 사용해 DOM 요소 선택
cy.contains(text) 지정된 텍스트를 포함하는 요소를 선택
cy.type(text) 선택한 입력 요소에 텍스트를 입력
cy.click() 선택된 요소를 클릭
cy.should(assertion, value) 선택된 요소의 상태를 확인
cy.invoke(functionName) 요소의 특정 메서드를 호출
cy.visit(url) 지정된 URL로 페이지 방문
cy.url() 현재 URL 확인
cy.as(alias) 선택된 요소에 별칭 부여

 

describe('로그인 화면', () => {
  it('사용자는 아이디와 비밀번호를 사용해서 로그인한다.', () => {
    // given - 로그인 화면이 그려진다. -> 로그인 페이지에 접근한다.

    cy.visit('/login');

    cy.get('[data-cy=emailInput]').as('emailInput'); // CSS selector를 emailInput으로
    cy.get('[data-cy=passwordInput').as('passwordInput'); // passwordInput으로

    // when - 아이디와 비밀번호를 입력하고 로그인 버튼을 클릭한다.

    cy.get('@emailInput').type('test@email.com'); // 해당 input에 type 뒤 입력
    cy.get('@passwordInput').type('password'); // 상동

    cy.get('@emailInput').invoke('val').should('eq', 'test@email.com'); // 해당 input에 val(값 가져오기)해서 should의 2번째 인자 값과 eq(equal)한지
    cy.get('@passwordInput').invoke('val').should('eq', 'password'); // 상동

    cy.get('[data-cy=loginButton]').should('exist').click(); // 해당 CSS selector가 존재하는지 확인 후 클릭
    cy.url().should('include', 'http://localhost:5173'); // 현재 URL이 should의 2번째 인자인 문자열을 포함하는지 확인

    // then - 로그인에 성공한다. -> 성공하고 메인 화면으로 이동한다.
  });
});

 

jest 때에도 element를 가져올 때 testId 이런 식으로 사용했는데, 이번에 테스트 하는 loginPage 라는 컴포넌트에도 비슷하게 data-cy라는 이름을 가지고 있다는 점을 알 수 있다.

 <Input
              id="emailInput"
              data-cy="emailInput"
              type="text"
              placeholder="이메일을 입력해주세요"
              onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
                setEmail(e.target.value)
              }
            />

 

 

이렇게 given, when까지 적어보고 테스트를 돌려봤다.

1초도 안되어서 테스트가 완료되었다.

오른쪽에 보면 실제로 서버에 request 요청을 보낸 것을 확인할 수 있다.

 

jest에서는 nock으로 이러한 행위를 mocking 했는데, cypress에서는 별도의 패키지 없이 interceptor 해주면 된다.

로그인 버튼의 존재를 확인하고 클릭하기 전에 네트워크 요청을 가로챈다.

    cy.intercept(
      {
        method: 'POST', // HTTP POST 요청을 가로챈다
        url: '/user/login', // URL이 '/user/loing'인 요청을 가로챈다
      },
      {
        token: 'AUTH_TOKEN', // 가로챈 요청에 대한 응답으로 { token: 'AUTH_TOKEN' }을 반환한다
      }
    ).as('login'); // 이 인터셉트를 @login 별칭으로 저장한다

 

Cypress에서 TypeScript 사용하기

npm install --save-dev @types/cypress

 

 

login은 js로 설치했는데 이제 나도 ts가 더 편한 사람이 되었다...

types를 설치해주면 메서드도 훨씬 쉽게 사용할 수 있으니 ts를 권장한다.

 

// tsconfig.json

"types": ["cypress"],
"include": ["src", "cypress/e2e/2-order/order-cy.ts", "**/*.ts"],

 

이 2줄만 추가해주면 끝!

 

types는 ts가 이 프로젝트에서 사용할 타입 정의 파일을 지정하는 것으로, cypress 타입 정의 파일을 사용하겠다는 의미다.

이를 통해서 cypress 테스트 코드에서 cypress의 API나 유틸리티를 사용할 수 있다.

 

include는 ts 컴파일러가 포함해야 할 파일 및 디렉토리를 저장한다.

src 디렉토리 아래의 모든 ts 파일을 컴파일한다는 뜻으로 cypress~.ts를 비롯 모든 ts 파일이 컴파일 대상이 된다.

 


 

참고 강의

 

2시간으로 끝내는 프론트엔드 테스트 기본기 강의 | 강병진 - 인프런

강병진 | 테스트코드! 어디서부터 시작해야할지 막막한 분들을 위해 준비했어요. 테스트 작성부터, 자동화를 통한 배포까지 한번에!, 테스트 코드를 작성하고 싶은 프론트엔드 개발자를 위한 강

www.inflearn.com

 

728x90