デザイン崩れを恐れずコンポーネント修正をしよう!~BackstopJS編~

こんにちは。KENTEMのフロントエンド担当です。

現在、私たちのチームではNext.jsを用いてクラウド製品の開発を行っています。

その中で頭を悩ませているのが、

  • 特定の画面に対応するため、コンポーネントを修正したところ、
    他の画面への想定していなかった影響により、デザインが崩れてしまった。

という問題です。

そんな問題を検知してくれる、Visual Regression Testing(以下、VRT)というテストが存在します。
今回は、そのVRTを行うことができる、BackstopJSというライブラリを試してみた話です。

どんなものが確認できるのか

html形式で結果レポートを作成できます。
左上のボタンでは、差分の有無でフィルターしたり、
右上のボタンでは、画像を非表示にしたりできます。

各画像をクリックすると拡大表示され、
修正前のREFERENCE
修正後のTEST
差分が表示されるDIFF
修正前・後をドラッグして見比べることのできるSCRUBBER
などを使い、画面上の何処で差分が発生しているのかを簡単に確認できます。
今回は、ヘッダーの「機能A ~ C」の間隔と、ダイアログの「閉じる」ボタンの色を変更しています。

なぜ、BackstopJSを選んだのか

VRTに関する記事を調べると、
世間的にはreg-suitというライブラリを採用するケースが多いようです。

そんな中、なぜBackstopJSを選んだのか?についてご説明します。

BackstopJSだけで完結できる

BackstopJSとreg-suitとでは、できる範囲に差があります。

画面キャプチャの取得 結果レポートの生成
BackstopJS
reg-suit ×

reg-suitでVRTを行う場合、画面キャプチャを別の手段で用意する必要があります。
それに対して、BackstopJSであれば画面キャプチャの取得も行えるため、手軽に感じました。

ローカル環境だけで完結できる

VRTを実施する場合、CIに組み込まれているケースが多いです。
reg-suitを採用する場合、画面キャプチャや結果レポートを外部ストレージへ保存する必要がありますが、
そのためのプラグインが、Amazon S3Google Cloud Storage用のものしか用意されていません。
しかし、弊社ではAzureを利用しており、reg-suitを採用する場合はプラグインを自力で用意する必要がありました。
今回はお試し導入ということもあり、手軽にVRTの実現が可能なツールを探していたところ、
画面キャプチャや結果レポートをローカル環境に保存しておくことが可能なBackstopJSに目を付けました。

使い方

インストール

今回はローカル環境にインストールします。

cd {インストール先ディレクトリ}
npm install --save-dev backstopjs

設定

initコマンドを実行すると、backstop_dataディレクトリとbackstop.jsonが作成されます。

npx backstop init

デフォルトではbackstop.jsonに設定を記載しますが、
jsファイルを作成して、それを設定ファイルにすることもできます。
JavaScriptで作成すると、定数での値の再利用ができて便利です。

JSON形式

{
  "id": "dummyId",
  ~~~ 中略 ~~~
}

JavaScript形式

module.exports = {
  id: 'dummyId',
  ~~~ 中略 ~~~
}

initコマンドで作成された設定ファイルの中を見てみましょう。

viewportsでは、画面サイズを指定できます。
配列で複数の画面サイズを指定できるため、レスポンシブ対応などに便利です。
今回はそのままの設定を使用します。

"viewports": [
  {
    "label": "phone",
    "width": 320,
    "height": 480
  },
  {
    "label": "tablet",
    "width": 1024,
    "height": 768
  }
],

scenariosで画面キャプチャを取得したいページを指定します。
必須となるのは、labelurlです。
labelは画面キャプチャのファイル名に使用されるため、分かりやすいものを付けておきましょう。
urlはそのまま、画面キャプチャを取得したいページのURLです。
delayを指定した場合、画面キャプチャを取得する前に指定した時間(ms)待機します。
読み込みに時間のかかるページで使用します。

"scenarios": [
  {
    "label": "testPage",
    "url": "http://localhost:3000/",
    "delay": 2000,
  }
],

実行

画面サイズとページの設定ができたので、実際に画面キャプチャを取得してみましょう。
referenceコマンドを実行します。
localhostを指定された方は忘れずにローカルサーバーを立ち上げておいてください。
backstop_data/bitmaps_referenceに画面キャプチャが保存されます。

npx backstop reference

JavaScript形式で設定ファイルを作成した場合、ファイル名の指定が必要です。

npx backstop reference --config="backstop.config.js"

次はtestコマンドを実行します。
backstop_data/bitmaps_testに画面キャプチャが保存され、
backstop_data/html_reportには、bitmaps_referencebitmaps_testを比較した結果レポートが保存されます。
結果レポートは自動で開かれますが、あとで見直したい場合はhtml_report/index.htmlを開いてください。

npx backstop test

こちらも同様に、JavaScript形式で設定ファイルを作成した場合、ファイル名の指定が必要です。

npx backstop reference --config="backstop.config.js"

導入してみた感想

自分の修正に自信が持てる

多くの画面で使用されているコンポーネントを修正する場合、どこかの画面でデザインが崩れていないか不安になります。
ローカル環境でVRTを実行することで、プッシュ前のタイミングで、自分の変更に問題ないことが確認できます。
少し大胆なリファクタリング等を行っても、自信を持ってプッシュできるようになりました。

ローカル環境で実行するかは規模と相談

当然ながら、確認したいページ、画面サイズが増えれば増えるほど、実行時間は長くなっていきます。
並列実行数を設定できるのですが、「10スレッドで動かせば10倍速だ!」というわけにもいきません。
マシンの性能や、ネットワーク速度がボトルネックとなっており、
並列実行数が増えれば増えるほど、各スレッドの動作が遅くなっていきます。

ローカル環境であることや、実行時間の長さから、

  • Aさんの環境ではうまくいくのにBさんの環境では読み込みが間に合わず、うまくキャプチャが取れない。

  • プルリクエスト提出前にはしっかりと確認したが、指摘対応の後の再確認をめんどくさがり省略してしまった。
    しかし、指摘対応が原因のデザイン崩れが発生していた。

などの問題が発生していました。

お試し導入ということもあり、手軽さを求めてローカル環境で実行できるものを選定しましたが、
本格的に使いたい!と言う場合はやはりCIへの組み込みを検討するべきかと思います。

まとめ

タイトルに~BackstopJS編~などと付いているので、
勘のいい方はお気づきかもしれませんが、続編が存在します。
現在、自作スクリプトを組み込んだ新たなVRT環境の構築中です。
完成した際には、またご紹介したいと思います。

KENTEMでは、様々な拠点でフロントエンドエンジニアを大募集しています!
建設×ITにご興味頂いた方は、是非下記のリンクからご応募ください。
hrmos.co hrmos.co hrmos.co