프로젝트에서 중요한 부분인 예약 기간 선택 기능에 오류가 있는 것을 발견했다.
의도한 대로 동작하지 않는 부분이 있었는데,이것을 하나하나 브라우저에서 실행해 테스트하는 대신 테스트 코드를 작성해두고 사용해보기로 했다.
TDD를 제대로 진행해보고 싶었다.
그냥 새로운 프로젝트부터 TDD를 하기에는 시간도 부족했지만 기능 명세가 부족해 오히려 유연하게 대처하지 못할 위험이 있었다. 모든 기능이 구현 된 이후 리팩토링 단계에서 진행하면 테스트 범위와 내용이 명확해질 뿐더러 에러 해결에도 큰 도움을 받을 수 있을 것이라고 생각했다.
테스트할 내용은 상세 페이지의 날짜 예약 컴포넌트의 함수들이다.
그런데... 테스트 코드를 작성하기 이전 설정부터 여러 오류를 만났기 때문에, 이 부분부터 정리해보았다.
자자... 그런데, 처음부터 순탄치가 않았다.
테스트 코드도 어떻게 작성해야할지 잘 모르겠는데, 설정부터가 난관이었다.
마주한 에러를 차근차근 정리해보자.
jsx 문법을 jest가 이해할 수 없기 때문에 발생한 에러로, 바벨을 설치 한 뒤 설정을 따로 해주어야 한다.
preset-evn와 react 외에도 한 개가 더 있어야 하는데, 플러그인으로 jsx 문법을 변환할 수 있도록 설정해준다.
module.exports = {
presets: [
['@babel/preset-env', { targets: { node: 'current' } }],
'@babel/preset-react',
],
plugins: ['@babel/plugin-transform-react-jsx'],
};
참고 문서:
참고한 스택오버플로우 답변
참고한 깃허브 babel-jest 관련 이슈
Jest 공식문서 - configuration
Jest 공식문서 - code-transformation
fetch 함수가 에러를 캐치하는 구문없이 실행되기 때문에 발생한 에러로, 테스트할 컴포넌트 코드 중 fetch 함수 구분에 catch문을 넣어 예외처리를 해주면 된다.
async function getUnavaliableDate() {
try {
const res = await fetch(unAvailableDatesUrl(stayIdParams, today));
const resJson = await res.json();
const undates = resJson.data.date;
setUnavailableDates(undates);
} catch (err) {
...
공식문서를 보니 Jest로 테스트가 실행되는 환경은 기본적으로 노드인데, 웹앱을 개발할 경우 브라우저와 유사한 환경인 jsdom을 대신 사용하라고 한다.
@jest-environment 문서 블록을 파일 위에 추가하면 해당 파일에서 테스트에 사용할 환경을 명시할 수 있다.
아래와 같이 가장 위에 작성해주었다.
/**
* @jest-environment jsdom
*/
import React from 'react';
import ReservationDate from './ReservationDate';
import { screen, render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
describe('ReservationDate', () => {
let getUnavaliableDate;
let startDate;
...
참고 문서:
Jest 공식문서 - test environment
이제 테스트 코드 작성에만 전념할 수 있는지 확인해보기 위해, 간단한 테스트를 작성 후 실행해보자.
테스트를 진행할 부분은 이곳, 상세페이지의 ReservationDate 컴포넌트이다. 날짜를 선택해주세요 버튼을 클릭하면 달력이 표시되고, 여기서 원하는 기간을 선택할 수 있다.
우선 설정을 마친 뒤 테스트를 정상적으로 실행할 수 있는 환경인지 확인해보기 위해, 간단한 테스트 코드까지만 작성 후 실행해보았다.
아래는 컴포넌트 렌더링 후 '날짜를 선택해주세요' 버튼을 찾아 클릭하는 것까지의 테스트 코드이다.
/**
* @jest-environment jsdom
*/
import React from 'react';
import ReservationDate from './ReservationDate';
import { screen, render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
describe('ReservationDate', () => {
let getUnavaliableDate;
let startDate;
let endDate;
let setStartDate;
let setEndDate;
beforeEach(() => {
getUnavaliableDate = jest.fn();
setStartDate = jest.fn();
setEndDate = jest.fn();
});
it('날짜선택 버튼 클릭 시 달력 창 띄우기', async () => {
await render(
<ReservationDate
startDate={startDate}
endDate={endDate}
setStartDate={setStartDate}
setEndDate={setEndDate}
/>
);
const selectDateButton = screen.getByText('날짜를 선택해주세요');
userEvent.click(selectDateButton);
});
});
휴, 성공했다!
테스트도 정상적으로 작동하고, 지금까지 작성한 테스트 코드도 통과했다.
이제, 본격적으로 자세한 테스트 코드를 작성해보자!