#4 React + Storybook + puppeteer + jest 개발환경 구축하기

Setup @storybook/addon-storyshots-puppeteer

vito
Jul 13 · 8 min read

🔖 목차

⛳ 목표

@storybook/addon-storyshots-puppeteer 사용하기

@storybook/addon-storyshots-puppeteer
storybook에서 출력하는 결과 화면 대해 이전 화면과 비교하여 변경사항을 이미지로 보여주는 storybook addon (storybook + jest + puppeteer)

1. @storybook/addon-storyshots-puppeteer 설치

발생하는 이슈는 이전 게시물에서 모두 해결했기 때문에 설치하고 설정만 수정하면 됩니다.

npm install --save-dev @storybook/addon-storyshots-puppeteer

이전 게시물에서 추가한 ./test/storyshots.test.js 파일에 다음 내용을 추가해 줍니다.

// ...
import { imageSnapshot } from '@storybook/addon-storyshots-puppeteer';
// ...
initStoryshots({
suite: 'Image storyshots',
test: imageSnapshot({
storybookUrl: 'http://localhost:6006',
}),
});

마지막으로 storybook을 실행시 포트번호가 6006 으로 실행되도록 package.json 의 scripts를 변경해줍니다.

{
// ...
"scripts": {
// ...
"storybook": "start-storybook -p 6006"
}
}

2. puppeteer 설정 최적화

puppeteer@storybook/addon-storyshots-puppeteer 를 참고하면 puppeteer 설정을 변경 가능하답니다.
아래에서 몇가지 필수적인 수정 사항들을 이야기 할께요.

화면 전체를 스크린샷 테스트

현재 설정은 스크롤을 내리지 않고 보여지는 화면에 대해서만 스크린샷 테스트를 진행합니다. 아래와 같이 puppeteer 옵션인 fullPage를 설정해주세요.

// ...const getScreenshotOptions = () => ({
fullPage: true,
});
// ...
initStoryshots({
suite: 'Image storyshots',
test: imageSnapshot({
storybookUrl: 'http://localhost:6006',
getScreenshotOptions,
//...
}),
});

이미지 파일등을 기다리고 스크린샷 테스트

현재 설정은 이미지 파일등을 기다리지 않고 스크린샷 테스트를 진행하는데요. 아래와 같이 puppeteer 옵션인 waitUntil을 설정해주세요.

// ...const getGotoOptions = () => ({
waitUntil: 'networkidle2',
});
// ...
initStoryshots({
suite: 'Image storyshots',
test: imageSnapshot({
storybookUrl: 'http://localhost:6006',
getGotoOptions,
//...
}),
});

모바일 화면에서 스크린샷 테스트

모바일 화면에 대한 스크린샷 테스트를 진행하고 싶다면 아래와 같이 puppeteer 의 page instance 옵션을 수정하면 됩니다.

// ...
const devices = require('puppeteer/DeviceDescriptors');
const iPhone = devices['iPhone 6'];const customizePage = page => page.emulate(iPhone);// ...initStoryshots({
suite: 'Image storyshots',
test: imageSnapshot({
storybookUrl: 'http://localhost:6006',
customizePage,
//...
}),
});

🤗 Complete!

테스트 실행해보기!

테스트 코드를 실행하기 전 storybook이 실행되있어야 합니다.

npm run storybook

이후 테스트를 실행합니다.

npm run test
그럼 아래와 같이 실행이 되며 스냅샷용 이미지 파일이 생성됩니다.

jest 를 실행했을때
생성된 스냅샷 이미지와 파일

만약 여기서 Header 컴포넌트에 내용을 추가후 npm run test 를 실행하면 아래와 같은 스냅샷 diff 결과를 보여주는 이미지 파일이 생성됩니다.

이전(왼쪽) / diff(가운데) / 현재(오른쪽)

터미널 결과창은 아래와 같습니다.

터미널 결과 창

여기서 u 를 누르면 스냅샷이 업데이트 됩니다.
그런데 그냥__image_snapshots__ 디렉토리를 지우고 npm run test 를 실행하는게 더 빠르네요. (최적화가 부족하네요😥 )

위 설정을 모두 마친 코드는 여기서 참고해주세요!

💡 회고

평소 storybook을 사용하다가, puppeteer 까지 붙여 보았는데요. 장점과 단점을 정리하자면 다음과 같습니다

😊 장점

  • 코드, 에셋 변경에 대한 UI 영향도를 즉각적으로 확인
  • 실제 출력 결과를 비교하여 개발자에게 알려주므로 편리

또한 React render 출력 결과를 스냅샷하여 비교하는 테스트의 다음 단점들을 해소해주지요.

  • React render 결과를 비교하는 방식에서는 UI가 바뀌지 않고 내부 구현 방식이 변경된 경우에도 테스트 실패로 떨어져서 번거로움.
  • React render 결과를 비교하는 방식에서는 render 결과가 바뀌어 diff 정보를 보여주어도 이 diff로 실제 UI가 어떻게 바뀌는지 직접 실행하여 눈으로 비교해야 되며 미세한 변화는 놓칠수 있음

😔 단점

브라우저 기본 폰트를 사용하는 사이트의 경우

  • 다른 브라우저 혹은 OS에서 테스트시 결과물이 달라져서 테스트가 실패할 가능성이 있음.
  • 위와 같은 이유로 테스트에 대한 CI 환경을 세팅하기 어려움

그 이외

  • puppeteer는 headless 크롬 브라우저에서 실행되기 때문에 다른 브라우저에서의 결과물은 확인할수 없음
  • git의 서로 다른 branch에서 작업하고 스크린샷 스냅샷을 업데이트하면 이미지의 경우 무조건 충돌이 발생하게 됨.

이런 단점들은 아래와 같은 정책으로 해결 가능합니다.

  1. CI에서는 screenshot test를 진행하지 않도록 설정합니다.
  2. 개발기간동안 screenshot test의 snapshot 파일을 git에 stage 하지 않습니다. 배포전 screenshot test를 실행하여 변경 사항을 diff 이미지로 확인후 git stage에 snapshot 파일을 추가합니다.

2번 방법의 경우 branch 별로 gitignore를 다르게 설정하면 더 편하게 정책을 적용 가능하겠네요.
참고: https://stackoverflow.com/questions/1836742/using-git-how-do-i-ignore-a-file-in-one-branch-but-have-it-committed-in-another


현재 작업중인 Toy Team Project에서 위의 환경을 구축하여 작업중에 있고 꽤나 편리하다는 생각을 가지고 있지만…

영향도가 적은 좋은 코드를 작성한다면 이런 도구는 필요 없겠네요 😆😆

읽어주셔서 감사합니다. 👋

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade