본문 바로가기
SPA/React

[React] Cypress로 내부 DOM 테스트하기

by J4J 2023. 4. 16.
300x250
반응형

안녕하세요. J4J입니다.

 

이번 포스팅은 cypress로 내부 dom 테스트하는 방법에 대해 적어보는 시간을 가져보려고 합니다.

 

 

 

Cypress로 내부 DOM 테스트할 때 발생되는 문제

 

예를 들어 다음과 같은 코드를 테스트한다고 가정해 보겠습니다.

 

import React from 'react';

const App = () => {
    return (
        <div>
            <div data-cy="title-wrapper1">
                <h2>첫번째 타이틀</h2>

                <ul>
                    <li data-cy="item">첫번째 아이템1</li>
                    <li data-cy="item">첫번째 아이템2</li>
                </ul>
            </div>

            <div data-cy="title-wrapper2">
                <h2>두번째 타이틀</h2>

                <ul>
                    <li data-cy="item">두번째 아이템1</li>
                    <li data-cy="item">두번째 아이템2</li>
                </ul>
            </div>
        </div>
    );
};

export default App;

 

 

 

테스트하고자 하는 것은 두 번째 wrapper의 내부에 있는 [data-cy=item]의 첫 번째 요소를 확인했을 때 요소가 가지고 있는 텍스트 값이 "두번째 아이템1" 인지 검증하는 것입니다.

 

해당 요소를 검증하는 것은 cypress에서 제공해 주는 다음 명령어들을 이용하면 어렵지 않게 느껴집니다.

 

  • get → selector에 해당되는 dom 요소 조회
  • first → 첫 번째 dom 요소 가져오기
  • should → 조건에 해당되는지 검증하기

 

 

반응형

 

 

그리고 이들을 이용하여 간단하게 테스트 코드를 작성하면 다음과 같이 될 것 같습니다.

 

describe('innerDom 테스트', () => {
    it('두번째 wrapper에 있는 첫번째 아이템 텍스트 확인하기', () => {
        // 페이지를 /로 이동
        cy.visit('/');

        // 두번째 wrapper의 첫번째 아이템 텍스트 검증 (X)
        cy.get('[data-cy=title-wrapper2]').get('[data-cy=item]').first().should('have.text', '두번째 아이템1');
    });
});

 

 

 

하지만 테스트를 동작시켜 보면 아래처럼 예상과 다른 결과를 확인할 수 있습니다.

 

cypress get 테스트 결과

 

 

 

문제 발생의 원인은 [data-cy=item]을 찾을 때 get을 사용했기 때문입니다.

 

일반적인 흐름으로 생각해 봤을 때 메서드체이닝을 이용하여 [data-cy=title-wrapper2]를 조회한 뒤 바로 [data-cy=item]을 조회하면 원하는 테스트가 수행될 것이라고 판단됩니다.

 

하지만 get은 이전에 동작된 체이닝과 상관없이 전체 화면에 보이는 [data-cy=item]을 조회하기 때문에 [data-cy=item]에 해당되는 4개의 yield가 생성되고 그중 첫 번째 dom을 가져오기 때문에 테스트가 실패됩니다.

 

 

 

 

find

 

위의 문제점을 해결할 수 있는 방법 중 한 가지는 find를 사용하는 것입니다.

 

find도 get과 동일하게 dom 요소를 조회하는 역할로써 사용된다는 공통점이 있지만 차이점으로는 get과 달리 이전에 동작된 체이닝의 결과를 기반으로 조회된다는 것입니다.

 

즉, [data-cy=item]을 조회할 때 get 대신 find를 사용한다면 원하는 테스트 결과를 확인할 수 있게 됩니다.

 

describe('innerDom 테스트', () => {
    it('두번째 wrapper에 있는 첫번째 아이템 텍스트 확인하기', () => {
        // 페이지를 /로 이동
        cy.visit('/');

        // 두번째 wrapper의 첫번째 아이템 텍스트 검증 (O)
        cy.get('[data-cy=title-wrapper2]').find('[data-cy=item]').first().should('have.text', '두번째 아이템1');
    });
});

 

cypress find 테스트 결과

 

 

 

 

within

 

within을 활용하면 get을 그대로 사용하면서 올바른 결과를 만들어 낼 수도 있습니다.

 

within의 역할은 이전에 만들어진 yield의 내부로 범위를 축소시킨 뒤 이후 테스트를 진행할 수 있게 도와줍니다.

 

within과 get을 활용하면 다음과 같이 테스트 코드를 작성해 볼 수 있고 테스트 결과도 올바르게 나오는 것을 확인할 수 있습니다.

 

describe('innerDom 테스트', () => {
    it('두번째 wrapper에 있는 첫번째 아이템 텍스트 확인하기', () => {
        // 페이지를 /로 이동
        cy.visit('/');

        // 두번째 wrapper의 첫번째 아이템 텍스트 검증 (O)
        cy.get('[data-cy=title-wrapper2]').within(($wrapper) => {
            cy.wrap($wrapper).get('[data-cy=item]').first().should('have.text', '두번째 아이템1');
        });
    });
});

 

cypress within 테스트 결과

 

 

 

 

 

 

 

 

이상으로 cypress로 내부 dom 테스트하는 방법에 대해 간단하게 알아보는 시간이었습니다.

 

읽어주셔서 감사합니다.

 

 

 

728x90
반응형

댓글