[NextJS] Cypress 테스트 코드 작성 해보기

    728x90

    매번 오류를 픽스할 때마다 느끼는 것이 있습니다.

     

    바로.... 

    이 코드를 짠게 내가 맞나?? 왜 이렇게 했더라?

     

    내가 작성했음에도 불구하고 30분은 다시 뜯어봐야
    코드의 목적을 알 수 있는 경우들이 많았습니다.

     

     

     

    그래서 오늘은 Cypress를 이용한 테스트 코드 작성법을 알아보려고 합니다! 

     


    코드 작성 이전에 테스트 코드에 대해 조금 알아보겠습니다.

     

    테스트코드 작성의 목적

    • 코드가 올바르게 작동하는가에 대한 확인
    • 다양한 조건 및 입력에서 컴포넌트가 제대로 (예상대로) 작동하는지 확인
    • 수월한 리팩토링을 위함
      - 프로젝트가 성장하면 리팩토링이 필요하기 마련
      → 테스트코드로 최소한의 기준, 안전망이 만들어짐

     

    테스트코드 작성의 장점

    • 작성한 코드가 기획 의도를 제대로 반영하였는지 확인 가능
    • 기획자와의 소통 도구로 사용 가능
    • 새로 합류한 개발자가 있다면 테스트만을 보고 컴포넌트 이해 가능

     

    테스팅 라이브러리 중 대표적인 예로 Jest와 Cypress가 있습니다.

    Jest는 주로 유닛/통합테스트에 사용되고, Cypress는 e2e테스트에 사용됩니다.



    유닛테스트

     

    가장 작은 단위의 테스트위에서 언급한 인풋이나 버튼들이 잘 렌더링 되는지


    - 이메일 인풋의 값이 잘 변경되는지
    - 버튼을 클릭하면 이벤트가 잘 실행되는지

     

     

    통합테스트

     

    다양한 컴포넌트 / 모듈 / 함수들이 잘 연결되는지 확인함

     

    - 로그인 버튼을 클릭하고, 로그인 성공 시 원하는 화면으로 잘 리다이렉트되는지

    - 로그인 실패하면 토스트 메시지가 잘 렌더링되는지

     

     

    e2e테스트

     

    실제 사용자인것처럼 테스트

     

    - 유닛테스트 + 통합테스트

    - 개발 비용이 가장 비싸다

     


    Cypress를 선택한 이유는...

    Jest와 Cypress 둘 다 사용해보았지만, Jest는 환경 설정이 복잡하고 테스트에 사용된 라이브러리마다 Boundary로 감싸줘야 하는 작업이 꽤나 피로했다.

    Cypress는 e2e테스팅으로 많이 사용하기 때문에, 실제 사용자처럼 페이지에 접속하여 테스트하는 것이고 설정도 그렇게 어렵지 않았기에 Cypress를 선택하게 되었다.

     

     

    자 이제 진짜로 Cypress로 테스트 코드를 작성해보자!

    일단 패키지 설치부터 해야 한다.

    npm install --save-dev cypress

     

    npm으로 cypress를 설치해주고

     

    타입스크립트를 사용중이라면 밑의 명령어로 type까지 설치해준다.

    npm install --save-dev @types/cypress

     

     

    설치가 끝났다면 package.json에서 아래와 같이 Cypress 실행 스크립트를 추가해준다.

     

     

     

    스크립트까지 추가해줬다면, 터미널에 아래 명령어를 입력한다.

    npm run cypress

     

    Cypress가 실행된 상태에서 E2E Testing을 클릭

    크롬 선택 → Running Chrome

     

    여기까지 따라왔다면 프로젝트 루트 폴더에 cypress 폴더가 생겼을 것이고,

    그 안에 e2e라는 폴더가 보일 것이다. (없으면 만들 것)

     

    다음은 간단한 예시로 로그인 테스팅 코드를 작성해보려고 한다.

    그 e2e 폴더에 login.cy.ts라는 파일을 만들고 다음과 같이 코드를 입력한다.

    용어를 하나씩 설명하기 보다는 코드를 먼저 보여주고 리뷰하는 형식으로 진행하겠다.

     

    describe('로그인 화면', () => {
      it('사용자는 아이디와 비밀번호를 사용해서 로그인한다', () => {
        // given - 로그인 화면에 접근한다
        cy.visit('http://localhost:3000/login');
        cy.get('[data-cy=emailInput]').as('emailInput');
        cy.get('[data-cy=passwordInput]').as('passwordInput');
    
        // when - 아이디와 비밀번호를 입력하고 로그인 버튼을 클릭한다
        cy.get('@emailInput').type('test@test.com');
        cy.get('@passwordInput').type('testPassword');
    
        cy.get('@emailInput').invoke('val').should('eq', 'test@test.com');
        cy.get('@passwordInput').invoke('val').should('eq', 'testPassword');
    
        cy.get('[data-cy=loginButton]').should('exist').click()
    
        // then - 메인 화면으로 이동한다
        cy.url().should('eq', 'http://localhost:3000/');
      });
    });

     

    기본적으로 테스트 코드는 given, when, then 형식을 따라서 작성한다.

    나처럼 주석으로 미리 어떤 시나리오인지 작성하고 코드를 작성하는 것을 추천한다.

     

    describe와 it은 보면 대충 느낌이 올 것이다.

     

    it은 실제 테스트 코드를 작성하는 함수이고, 테스트 코드가 어떤 역할을 하는지 작성하는 곳이다.

     

    describe는 그러한 it이나 test를 모아놓은 묶음이라고 보면 된다.

     

    cy.visit('http://localhost:3000/login');

     

    cy.visit은 입력된 url에 접속하는 함수이다.

     

    cy.get('[data-cy=emailInput]').as('emailInput');

     

    cy.get은 현재 접속된 페이지의 엘리먼트를 가져오는 함수이다.

    data-cy=emailInput이라고 되어있는 이유는

     

    로그인 페이지에서 input에 data-cy라는 프로퍼티를 emailInput이라고 선언해주었기 때문이다.

     

    즉, 가져오려고 하는 엘리먼트에 data-cy 프로퍼티를 부여해주면 위와 같이 불러올 수 있게 된다.

    구문 뒤에 as('emailInput')이 붙은 이유는 가져온 엘리먼트에 emailInput이라고 이름을 붙여준 것이다.

     

    cy.get('@emailInput').type('test@test.com');

     

    이 구문은 위에서 emailInput이라고 선언된 엘리먼트를 가져와서

    test@test.com이라고 타이핑해주라는 구문이다.

    (패스워드도 마찬가지이다)

     

    cy.get('@emailInput').invoke('val').should('eq', 'test@test.com');

     

    이 구문은 input에 입력된 값이 test@test.com이 맞는지 검증하는 구문이다. (eq = equal)

     

     cy.get('[data-cy=loginButton]').should('exist').click();

     

    이 구문은 loginButton을 찾아서 만약 버튼이 존재한다면 클릭하라는 구문이다.

     

    cy.url().should('eq', 'http://localhost:3000/');

     

    이 구문은 로그인에 성공했다면 메인 페이지로 이동할 것이기 때문에,

    현재 경로가 메인 페이지인지 확인하는 구문이다.

     

     

    이런식으로 작성하고 테스트를 실행하게 되면

     

     

    테스트에 통과하게 된다!!!

    728x90

    'JS > React' 카테고리의 다른 글

    [NextJS] CSR, SSR 그리고 SSG의 차이  (0) 2024.02.27
    [리액트] 공부일지-3  (0) 2022.01.12
    [리액트] 공부 일지-2  (0) 2022.01.06
    [리액트] 공부 일지-1  (0) 2021.12.31
    [리액트] styled-component 사용법  (0) 2021.12.29

    댓글