Help us understand the problem. What is going on with this article?

Storybook で Snapshot テストを行うのに便利な Snapshot, Snapshot + Puppeteer を動かす

Stories ごとに Snapshot と Puppeteer によるリグレーションテストを書かずに,自動テストできないか調べたらうまくいく方法を見つけたのでメモ


To use StoryShots, you must use your existing Storybook stories as the input for Jest Snapshot Testing.

StoryShots

Snapshots は stories をテストケースとして Jest に渡すようです。

まずインストール

# create vue project
vue create storybook-puppeteer
cd storybook-puppeteer

# create storybook sample
sb init
npx @storybook/cli init
yarn storybook

# add jest
yarn add --dev jest

いつもの
いつもの

Storyshots, Storyshots-puppeteer を追加

ここで Storybook の拡張,Storyshots, Storyshots-puppeteer を追加します。

yarn add --dev @storybook/addon-storyshots @storybook/addon-storyshots-puppeteer puppeteer

Snapshot のテストファイルを作成

分かりやすいように test フォルダにテストファイルを作成します。

test
├── Storyshots-puppeteer.test.js
└── Storyshots.test.js
Storyshots.test.js
import initStoryshots from "@storybook/addon-storyshots";

initStoryshots();
Storyshots-puppeteer.test.js
import initStoryshots from "@storybook/addon-storyshots";
import { imageSnapshot } from "@storybook/addon-storyshots-puppeteer";

initStoryshots({ suite: "Image storyshots", test: imageSnapshot() });

ファイルを配置して,Storybook をブラウザで表示できる状態にしてから テストを実行します。1

> yarn test
yarn run v1.22.0
$ jest
 PASS  test/Storyshots.test.js
 › 4 snapshots written.
 PASS  test/Storyshots-puppeteer.test.js
  ● Console

    console.info node_modules/vue/dist/vue.common.dev.js:9051
      Download the Vue Devtools extension for a better development experience:
      https://github.com/vuejs/vue-devtools
    console.info node_modules/vue/dist/vue.common.dev.js:9060
      You are running Vue in development mode.
      Make sure to turn on production mode when deploying for production.
      See more tips at https://vuejs.org/guide/deployment.html

 › 4 snapshots written.

Snapshot Summary
 › 8 snapshots written from 2 test suites.

Test Suites: 2 passed, 2 total
Tests:       8 passed, 8 total
Snapshots:   8 written, 8 total
Time:        4.553s, estimated 5s
Ran all test suites.
✨  Done in 5.56s.


これで test フォルダ配下に __image_snapshots__, __snapshots__ が作成されます。

test
├── Storyshots-puppeteer.test.js
├── Storyshots.test.js
├── __image_snapshots__
│   ├── storyshots-puppeteer-test-js-image-storyshots-button-emoji-1-snap.png
│   ├── storyshots-puppeteer-test-js-image-storyshots-button-jsx-1-snap.png
│   ├── storyshots-puppeteer-test-js-image-storyshots-button-text-1-snap.png
│   └── storyshots-puppeteer-test-js-image-storyshots-welcome-to-storybook-1-snap.png
└── __snapshots__
    └── Storyshots.test.js.snap

この状態で Stories の表示を換えてみましょう。

--- a/stories/1-Button.stories.js
+++ b/stories/1-Button.stories.js
@@ -24,6 +24,6 @@ export const Jsx = () => ({

 export const Emoji = () => ({
   components: { MyButton },
-  template: '<my-button @click="action">😀 😎 👍 💯</my-button>',
+  template: '<my-button @click="action">📦 🐭 🎧 💻</my-button>',
   methods: { action: action("clicked") }
 });

テストを実行すると Snapshot と差分ができるのでテストに失敗します。

> yarn test
yarn run v1.22.0
$ jest
 FAIL  test/Storyshots.test.js
  ● Storyshots › Button › Emoji

    expect(received).toMatchSnapshot()

    Snapshot name: `Storyshots Button Emoji 1`

    - Snapshot  - 1
    + Received  + 1

      <button
        style="border: 1px solid #eee; border-radius: 3; background-color: rgb(255, 255, 255); cursor: pointer; padding: 3px 10px;"
      >
    -   😀 😎 👍 💯
    +   📦 🐭 🎧 💻
      </button>

      at match (node_modules/@storybook/addon-storyshots/dist/test-bodies.js:16:30)
      at node_modules/@storybook/addon-storyshots/dist/test-bodies.js:25:16
      at Object.<anonymous> (node_modules/@storybook/addon-storyshots/dist/api/snapshotsTestsTemplate.js:42:20)

 › 1 snapshot failed.
 FAIL  test/Storyshots-puppeteer.test.js (5.318s)
  ● Console

    console.info node_modules/vue/dist/vue.common.dev.js:9051
      Download the Vue Devtools extension for a better development experience:
      https://github.com/vuejs/vue-devtools
    console.info node_modules/vue/dist/vue.common.dev.js:9060
      You are running Vue in development mode.
      Make sure to turn on production mode when deploying for production.
      See more tips at https://vuejs.org/guide/deployment.html

  ● Image storyshots › Button › Emoji

    Expected image to match or be a close match to snapshot but was 0.10145833333333333% different from snapshot (487 differing pixels).
    See diff for details: /Users/n07/storybook-puppeteer/test/__image_snapshots__/__diff_output__/storyshots-puppeteer-test-js-image-storyshots-button-emoji-1-diff.png

      at node_modules/@storybook/addon-storyshots-puppeteer/dist/imageSnapshot.js:74:43
      at step (node_modules/@storybook/addon-storyshots-puppeteer/dist/imageSnapshot.js:44:23)
      at Object.next (node_modules/@storybook/addon-storyshots-puppeteer/dist/imageSnapshot.js:25:53)
      at fulfilled (node_modules/@storybook/addon-storyshots-puppeteer/dist/imageSnapshot.js:16:58)

 › 1 snapshot failed.
Snapshot Summary
 › 2 snapshots failed from 2 test suites. Inspect your code changes or run `yarn test -u` to update them.

Test Suites: 2 failed, 2 total
Tests:       2 failed, 6 passed, 8 total
Snapshots:   2 failed, 7 passed, 9 total
Time:        6.215s
Ran all test suites.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

コンソールにテストに失敗した差分が表示されました。加えて, test/__image_snapshots__/__diff_output__ に (Snapshot 前 + 差分 + 現在) の画像ファイルが生成されます。

storyshots-puppeteer-test-js-image-storyshots-button-emoji-1-diff.png

もし修正内容が正しければ yarn test -u で Snapshot をアップデートしてください。

> yarn test -u
yarn run v1.22.0
$ jest -u
 PASS  test/Storyshots.test.js
 › 1 snapshot updated.
 PASS  test/Storyshots-puppeteer.test.js
  ● Console

    console.info node_modules/vue/dist/vue.common.dev.js:9051
      Download the Vue Devtools extension for a better development experience:
      https://github.com/vuejs/vue-devtools
    console.info node_modules/vue/dist/vue.common.dev.js:9060
      You are running Vue in development mode.
      Make sure to turn on production mode when deploying for production.
      See more tips at https://vuejs.org/guide/deployment.html

 › 1 snapshot updated.

Snapshot Summary
 › 2 snapshots updated from 2 test suites.

Test Suites: 2 passed, 2 total
Tests:       8 passed, 8 total
Snapshots:   2 updated, 6 passed, 8 total
Time:        5.106s, estimated 6s
Ran all test suites.
✨  Done in 6.78s.

テストファイルを Snapshot,Image-Snapshot 用に2つ書くだけで Snapshot テストができるようになりました。


個々のコンポーネントに対して Snapshot, Image-Snapshot のテストコードを一つづつ書く状況になり,それがイヤだったので色々調べてたら動くようになりました。

これで楽できるのはいいのですが,まだ個人的に Stories はどの単位で書くべきなのか,というのがいまいち掴めてないのでそこも少し考えないといけないなあ,と。


  1. ビルドした状態でもテストできるようですが,今回は簡単にするため立ち上げた状態で進めます。 

muro3r
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした