지난 포스트에 이어 이번 글에서는 Storybook에서 스냅샷을 이용하여 컴포넌트 테스트 자동화를 해보겠습니다.

🖼️ Snapshot Testing?

snapshot 테스트 케이스는 UI component를 렌더링한 뒤, 스크린샷을 찍고, 테스트 부근에 저장된 레퍼런스 이미지와 찍은 것들을 비교합니다.

만약 이전에 찍었던 이미지와 테스트했을 때와의 이미지가 다르다면 테스트에 실패합니다.

두 이미지가 다르다는 것은 예상치 못한 변화 혹은 스크린샷이 UI component의 새로운 버전으로 업데이트되어야 할 때를 말합니다.

기존에 React.js를 테스트할 때, Jest에 Snapshot Testing을 사용하곤 하지만 이번에는 Storybook에서 지원하는 addon 중 하나인 Storyshots를 사용해보겠습니다.

🔫 Storybook의 Storyshot

Storyshot을 이용하면 .stories.js에 정의한 대로 snapshot을 정의하며 이를 토대로 테스트를 진행합니다.

React에서는 가상DOM을 이용하기 때문에 테스트를 위한 렌더링을 하기 위해서는 react-test-renderer를 설치해야 합니다.

설치 및 적용

먼저 storyshots addon과 react-test-renderer을 설치해줍니다.

// npm
npm install -d @storybook/addon-storyshots react-test-renderer

// yarn
yarn add --dev @storybook/addon-storyshots react-test-renderer

그런 다음 /src/test라는 폴더를 만들고 storybook.test.js라는 파일에 아래와 같이 작성해줍니다.

import initStoryshots from '@storybook/addon-storyshots';
initStoryshots({ /* 설정 옵션 */ });

그럼 이제 scripts 명령어로 테스트를 시작해줍니다.

npm test

yarn test

성공.PNG

위 사진과 같이 나오면 테스트를 성공한 것입니다.

아까만든 test폴더를 보면 __snapshots__ 라는 폴더가 생기고 안에 든 파일을 보면 스냅샷이된 파일을 볼수 있습니다.

// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Storyshots TaskInput default 1`] = `
<div
  className="TaskInput-container"
>
  <div
    className="TaskInput"
  >
    <input
      className="TaskInput-input"
      onChange={[Function]}
      placeholder="Please input your task"
      type="text"
      value=""
    />

이 처럼 스냅샷이 저장되고 테스트 케이스가 여기에 명시된 스냅샷 시나리오와 일치하면 테스트를 성공하게 됩니다.

더욱 자세한 내용) https://jestjs.io/docs/en/snapshot-testing

스냅샷 업데이트

스냅샷에 있는 테스트 케이스를 수정하고 싶을 때는 yarn test를 통해 테스트를 끝낸 뒤 u를 누르거나
package.jsonscripts에 아래와 같이 수정하고 실행합니다.

...
    "test-update": "react-scripts test -u"
...

테스팅 할 때 쓰면 좋은 Addon

  • 테스트 케이스를 동적으로 수정할 수 있게 해준다.
    @storybook/addon-knobs

  • 반응형을 쉽게 확인 할 수 있게 해준다.
    @storybook/addon-viewport

  • 스토리북에 메보를 남길 수 있게 해준다
    @storybook/addon-notes

👍 마치며 ...

저도 배우면서 사용해봤는데 실제 프로젝트에 도입했을 때, 이전에 겪었던 컴포넌트를 설계하고 병합하여 페이지를 만드는 과정에서 들였던 수고를 덜 수 있을 것 같습니다.

또한 스토리북에서 지원하는 addon 중에서 필요한 것을 골라서 프로젝트에 적절하게 적용한다면 더욱 효율적으로 컴포넌트를 관리하고 팀원과 공유할 수 있을 것 같습니다.

Ps. 글에 수정사항, 오류 지적은 언제나 환영입니다 :)