📸

CIで実行しないスナップショットテストがすごく便利

2021/12/29に公開

Webフロントエンド開発でスナップショットテストを実行することは一般的になっていて、自分のやっているサービスでも導入したかったんですが以下の要因から導入が難しい状態でした。

  • アニメーション要素のある画面が多く、ちょっとタイミングがずれると差分が出やすい
    • それ起因でCIが通ったり落ちたりするのをどうにかするコストを負いたくない

そこでスナップショットテストというよりも手軽に見た目の差異を網羅的にチェックできることを目的として、CIではスナップショットテストを実行せず手元で実行した結果の画像をコミットする運用を試してみるととても快適でした。

  • CIではないが、手元で見た目の差異が出たかを網羅的にチェックできる
    • 特にCSSのリファクタを大量にやるタスクと重なっていたので、スナップショットに差異がなければ確信を持って大胆にリファクタを進めることができる
  • 常に -u フラグ付きで実行してアニメーションなどによるFlakyさでテストが落ちることによる不快感を感じないようにする
    • アニメーションで差異が出てしまった場合はしょうがないとして人間が目で見てコミットしないという雑運用😇
    • thresholdなどを細かく気にするなど、CIでスナップショットテストをする際のFlakyさに向き合う必要がない

デメリットとしてはCIで実行していないので手元で実行しないメンバーがいれば差分がわかりませんがそれは導入前と同じなので気にしていません。

ツールとしてはStorybookを使っているのでStoryshotsを使いたかったんですが、StoryshotsはJestに依存していて手元でVite+Jestの環境がいまいち整えて切れてないのでPlaywrightを使用しました。

https://playwright.dev/

Playwrightはこんな感じのAPIです。

test('snapshot test', async ({ page }) => {
  // top page
  await page.goto('http://localhost:3000/');
  await page.locator('text=Top').waitFor();
  expect(await page.screenshot()).toMatchSnapshot('top.png');
});

PlaywrightはStoryshotsと違ってビルド構成を問わないのでVite/Reactなまだ枯れてない環境でも問題なく導入できました。ローカルなどにWebアプリを立ち上げておく必要はありますがどうせローカルで開発中に使うものなので特にデメリットなく使えています。

Discussion