본문 바로가기
SPA/React

[React] Cypress API 요청 기다리기

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

안녕하세요. J4J입니다.

 

이번 포스팅은 cypress에서 api 요청 기다리는 방법에 대해 적어보는 시간을 가져보려고 합니다.

 

 

 

API 요청을 기다려야 하는 경우

 

cypress를 사용하면서 api 요청을 기다려야 하는 경우는 정말 단순하게 api 요청 처리가 오래 걸리는 작업들이라고 얘기할 수 있습니다.

 

대부분의 api를 처리할 때 시간이 오래걸리지 않겠지만 시간이 오래 걸리는 일부 api들에 대해서 cypress 테스트를 진행하려고 하면 api가 응답되는 시간을 모두 기다리지 않고 이후 처리를 진행하기 때문에 생각하던 것과 다른 결과를 얻게 됩니다.

 

 

 

이와 같은 상황을 테스트를 위해 다음과 같은 api를 이용하여 데이터를 호출한 뒤 화면에 그려주는 코드를 작성해 볼 수 있습니다.

 

데이터 호출 api

 

import axios from 'axios';
import React, { useEffect, useState } from 'react';

interface Data {
    name: string;
    value: number;
}

const App = () => {
    /**
     * useState
     */
    const [datas, setDatas] = useState<Data[]>([]);

    /**
     * api
     */
    const api = {
        getData: async () => {
            const res = await axios.get('http://localhost:8080/getData');
            if (res.data) {
                setDatas(res.data);
            }
        },
    };

    /**
     * useEffect
     */
    useEffect(() => {
        api.getData();
    });

    return (
        <div>
            <div>
                <h2 data-cy="name">name : base</h2>
                <p data-cy="value">value : 0</p>
            </div>

            {datas.map((data) => (
                <div key={data.value}>
                    <h2 data-cy="name">name : {data.name}</h2>
                    <p data-cy="value">value : {data.value}</p>
                </div>
            ))}
        </div>
    );
};

export default App;

 

 

 

api에는 강제로 5초 뒤에 response를 전달하도록 설정을 해놨고 위의 코드를 이용하여 cypress 테스트 코드를 작성해 보면 다음과 같은 결과를 확인할 수 있습니다.

 

describe('API 호출하기', () => {
    it('getData를 호출하여 데이터 검증하기', () => {
        // 페이지를 /로 이동
        cy.visit('/');

        // name dom 요소의 갯수가 4개인지 검증
        cy.get('[data-cy=name]').should('have.length', 4);
        // name dom 마지막 요소의 텍스트가 third인지 검증
        cy.get('[data-cy=name]').last().should('have.text', 'name : third');
        // value dom 마지막 요소의 텍스트가 3인지 검증
        cy.get('[data-cy=value]').last().should('have.text', 'value : 3');
    });
});

 

cypress 테스트 결과

 

 

 

결과를 확인해보면 화면에는 데이터를 올바르게 가져와 그려주고 있지만 cypress는 api 요청에 대한 응답을 끝까지 기다리지 않고 결과를 출력하여 테스트가 실패하는 모습을 볼 수 있습니다.

 

이런 상황들이 발생했을 때 해결할 수 있는 방법들에 대해 간단히 소개해보겠습니다.

 

 

반응형

 

 

Timeout Wait

 

api 요청을 기다리기 위해 cypress에서 제공해 주는 커맨드로 wait을 활용해 볼 수 있습니다.

 

그중 timeout을 설정하는 것이 있습니다.

 

 

 

timeout은 말 그대로 지정한 시간만큼 테스트를 멈춘 뒤 시간이 지나면 이후 테스트 코드들에 대해 검증을 시작합니다.

 

단위는 ms로 다음과 같이 5초 동안 기다리는 코드를 작성하여 테스트를 해보면 정상적으로 통과되는 것을 볼 수 있습니다.

 

describe('API 호출하기', () => {
    it('getData를 호출하여 데이터 검증하기', () => {
        // 페이지를 /로 이동
        cy.visit('/');

        // 5초 동안 기다리기
        cy.wait(5000);

        // name dom 요소의 갯수가 4개인지 검증
        cy.get('[data-cy=name]').should('have.length', 4);
        // name dom 마지막 요소의 텍스트가 third인지 검증
        cy.get('[data-cy=name]').last().should('have.text', 'name : third');
        // value dom 마지막 요소의 텍스트가 3인지 검증
        cy.get('[data-cy=value]').last().should('have.text', 'value : 3');
    });
});

 

timeout wait 테스트 결과

 

 

 

하지만 여기서 한 가지 생각해야 될 점은 테스트는 성공했지만 api 요청 시간이 얼마나 걸리지도 모르는 상황에서 timeout을 설정하는 것은 찝찝함을 충분히 남길 수 있습니다.

 

서버의 상황에 따라 속도가 느리거나 빠른 상황이 반복적으로 발생될 수 있기에 정확한 시간을 설정하기가 힘들기에 더 좋은 방법이 없을지에 대해 고민을 해볼 수 있습니다.

 

 

 

 

Intercept Wait

 

다음 방법으로는 intercept를 이용하는 방법이 있습니다.

 

intercept도 cypress에서 기본적으로 제공해 주는 커맨드이며 역할은 네트워크 request와 response를 spy와 stub을 해줍니다.

 

사용하는 방법은 정말 다양하게 있기에 자세한 사항은 Cypress 공식 문서를 참고해주시길 바라며 저는 하나의 방법을 선택하여 다음과 같이 timeout을 대신하는 코드를 작성해 보겠습니다.

 

describe('API 호출하기', () => {
    it('getData를 호출하여 데이터 검증하기', () => {
        // 페이지를 /로 이동
        cy.visit('/');

        // /getData api intercept alias 처리하기
        cy.intercept({
            method: 'get',
            url: '/getData',
        }).as('getData');
        // /getData api 요청이 완료될때까지 기다리기
        cy.wait('@getData');

        // name dom 요소의 갯수가 4개인지 검증
        cy.get('[data-cy=name]').should('have.length', 4);
        // name dom 마지막 요소의 텍스트가 third인지 검증
        cy.get('[data-cy=name]').last().should('have.text', 'name : third');
        // value dom 마지막 요소의 텍스트가 3인지 검증
        cy.get('[data-cy=value]').last().should('have.text', 'value : 3');
    });
});

 

intercept wait 테스트 결과

 

 

 

timeout과 달리 intercept는 api 요청에 대한 response가 전달되는 시점을 정확히 파악하여 그 순간까지 테스트를 멈추고 있다가 response가 전달되면 이후 테스트 코드를 검증하는 것을 볼 수 있습니다.

 

위의 결과들을 확인해 본 결과로 api 요청을 기다릴 땐 timeout보다는 intercept를 활용하면 더 명확한 결과들을 만들어낼 수 있는 것으로 보입니다.

 

 

 

 

 

 

 

 

 

이상으로 cypress에서 api 요청 기다리는 방법에 대해 간단하게 알아보는 시간이었습니다.

 

읽어주셔서 감사합니다.

 

 

 

728x90
반응형

댓글