Enzyme 테스트 코드

김영훈·2022년 9월 12일
0

testcode

목록 보기
1/1

최근의 작업한 프로젝트는 클래스형 컴포넌트가 사용된 레거시 코드에 새로운 기능을 추가하고 Enzyme을 이용한 snapshot 테스트 코드를 작성하는 것이었다.

테스트 코드를 이렇게 대량으로 작성했던 적은 없어서 기록으로 남기기 위해 글을 작성하려한다.

작업 목표

이전 커버리지는 90%이나 현재 수정 추가된 부분들로 인한 Failed가 많아서 Failed 처리 및 신규 기능 테스트 코드 작성으로 85%를 달성하는 조건이었다.

우선 테스트 코드 작성에 앞서 유감스럽게도 Enzyme을 React 최신 버전 지원을 안한다.
따라서 이 프로젝트가 사용하고 있는 17 버전에서 사용하기 위해선 Adapter 라이브러리를 설치 해줬어야 한다.
설치 후 아래 코드를 추가해줘야한다.


import Adapter from '@wojtekmaj/enzyme-adapter-react-17';


Enzyme.configure({ adapter: new Adapter() });

스냅샷 테스팅

스냅샷 테스팅은 렌더링된 결과가 이전에 결과와 일치하는지 확인하는 작업

아래는 예로 가져온 DateTime 컴포넌트의 테스트 코드이다.
최하위 View 컴포넌트이기에 DOM 확인 정도의 처리만하고 있다.

DateTime.js


function DateTime({ className, timestamp }: Props) {
  const today = new Date(new Date().toDateString()).valueOf();

  return (
    <span className={className}>
      {today <= timestamp ? (
         <FormattedDate value={timestamp} formats={{ locale }} {...format} />
      ) : (
        <FormattedTime value={timestamp} />
      )}
    </span>
  );
}

export default DateTime;

DateTime.test.js


describe('<DateTime />', () => {
  const todayTimestamp = new Date(new Date().toDateString()).valueOf();

  const store = getStore({});
  it('should return time, if they are same.', () => {
    const wrapper = mount(
      <IntlProvider locale="en" key="en">
        <Provider store={store}>
          <DateTime timestamp={todayTimestamp} />
        </Provider>
      </IntlProvider>,
    );
    expect(wrapper.text()).toEqual('12:00 AM');
  });

  it('should return time, if the current timestamp is over it.', () => {
    const noon = new Date(todayTimestamp).setHours(12);
    const wrapper = mount(
      <IntlProvider locale="en" key="en">
        <Provider store={store}>
          <DateTime timestamp={noon} />
        </Provider>
      </IntlProvider>,
    );
    expect(wrapper.text()).toEqual('12:00 PM');
  });

  it('when receiveDate is same year', () => {
    const today = Date.now();
    const timestamp = today - 1000 * 60 * 60 * 24 * 3;
    const wrapper = mount(
      <IntlProvider locale="en" key="en">
        <Provider store={store}>
          <DateTime timestamp={timestamp} />
        </Provider>
      </IntlProvider>,
    );
    const dateStr = new Date(timestamp).toLocaleString('en', {
      month: 'short',
      day: '2-digit',
    });
    expect(wrapper.text()).toContain(dateStr);
  });

  it('when receiveDate is not same year', () => {
    const timestamp = 1618431328353;
    const wrapper = mount(
      <IntlProvider locale="en" key="en">
        <Provider store={store}>
          <DateTime timestamp={timestamp} />
        </Provider>
      </IntlProvider>,
    );

    expect(wrapper.text()).toEqual('15/04/2021');
  });
});

mount를 통해서 IntlProvider내 DateTime 컴포넌트를 테스트하였다.

mount는 Enzyme을 통하여 리액트 컴포넌트를 렌더링 해준다. wrapper 를 통해서 우리가 props 조회, DOM 조회, state 조회 등을 할 수 있다.

그 이외에 shallow가 있는데 이는 리액트 컴포넌트를 렌더링 하지 않는다. div가 최상단이라는 의미인데 컴포넌트 내부까지 테스트할 필요가 없을 때 사용한다.
wrapper.instance(), wrapper.state()를 통해서 컴포넌트의 method, state에 쉽게 접근하여 비교 가능하다.

결론

Enzyme의 경우 react-testing-library와는 다르게 직관적이고 쉬운 느낌이다. state와 method에 접근하기 쉬웠고 snapshot만 비교해도 엄청난 coverage가 나와서 RTL에서 branch 수치 올리려면 힘들었는데 편하게 작업했던 것 같다.

profile
개인적인 기록.

0개의 댓글