RAKUS Developers Blog | ラクス エンジニアブログ

株式会社ラクスのITエンジニアによる技術ブログです。

手軽に始めるビジュアルリグレッションテスト【導入記】

f:id:tech-rakus:20211008131412p:plain

こんにちは!フロントエンドエンジニアの松本です。
私が担当するプロダクトは今年で20年に到達し、ご長寿プロダクトとなりました。 息の長いプロダクトにはレガシー化が付き物でありますが、レガシー化を進めないためにも、日々技術を最新化するためのリファクタリングが必要です。
今回は、品質を担保しつつ安全にリファクタリングを進めるために、ビジュアルリグレッションテストを試験導入してみました。想像以上に導入が簡単だったので導入方法の紹介と、苦労した点、導入してよかった点について紹介します。

ビジュアルリグレッションテストとは

ビジュアルリグレッションテストは、画面に表示されたページや要素が期待通りに表示されているかを、修正前後の画像比較で検証するテストです。 図のように、テキスト色をはじめとするスタイルや、要素の配置やサイズといったレイアウトの差分を検出できます。

ビジュアルリグレッションテストの例

また、ビジュアルリグレッションテストでは以下の観点の検証が可能です。

  • スタイルやレイアウトが期待通り表示されているか
  • 画像や埋め込みiframeがリンク切れしていないか
  • 400エラーや500エラーなど、予期せぬエラー画面が表示されていないか

試験導入の経緯

開発案件で、見た目に変化を与えない系のリファクタリングを実施しました。(例:JavaScriptライブラリのバージョンアップ対応)

見た目が変わっていないことを担保するテスト方法の1つとして、「修正前の画面と、修正後の画面を目視でチェックしていく」方法があります。 リファクタリング件数が少ない場合にはこちらの方法を採用しても良いのですが、

  • 今回はリファクタリング件数が多い且つ、クロスブラウザでのテストが必須なので、テスト工数の見積もりが大きくなった
  • また、目視でのチェックは精度にバラつきが出る(件数も多いので人的エラーをゼロにする自信がなかった)

よって、目視でのチェックは断念しました。

そこで、ビジュアルリグレッションテストならこれらの課題を解決できそうだと踏み、試験導入に至りました。続いて、実際に使用したライブラリを紹介します。

今回使用したライブラリ

今回は2つのNode.jsライブラリを使用しました。
画面のスクリーンショットを収録するためにPlaywright、収録したスクリーンショットを比較するためにreg-suitを使用します。

  • Playwright

  • reg-suit

    • ビジュアルリグレッションテストのテスティングライブラリ
    • 修正前後の画像を比較し、差分結果をHTMLレポートとして出力
    • 外部クラウドストレージへの画像保存も可能 ※今回はこの件には触れません
    • reg-suitはCLIなので、ローカルマシンやCI上での実行が可能 ※今回はこの件には触れません

導入方法

Playwrightの導入

まずは画面のスクリーンショットを収録するライブラリPlaywrightをインストールします。 テストプロジェクト上に移動して、以下npmコマンドを実行します。

$ npm i -D playwright

Playwrightと、ChromiumFirefoxWebKitブラウザーバイナリがインストールされます。

reg-suitの導入

次に修正前後の画像を比較して、検証レポートを出力するライブラリreg-suitをインストールします。 テストプロジェクト上に移動して、以下npmコマンドを実行します。

$ npm i -D reg-suit

インストールが完了したら、reg-suitの初期設定をするために以下のコマンドを実行します。
いくつか任意設定がありますので、プロジェクトの要件に合わせて適宜入力してください。 今回の試験導入段階ではCIやクラウドストレージとの連携はせずに、ローカル上でのテスト実行を想定しているので、プラグインの導入は見送りました。

$ npx reg-suit init

任意設定を表示する▼

? Plugin(s) to install (bold: recommended) (Press <space> to select, <a> to toggle all, <i> to invert selection)
※インストール時に合わせて導入したいプラグインがあれば選択してください
 ( )  reg-keygen-git-hash-plugin : Detect the snapshot key to be compare with using Git hash.
 ( )  reg-notify-github-plugin : Notify reg-suit result to GitHub repository
 ( )  reg-publish-s3-plugin : Fetch and publish snapshot images to AWS S3.
 ( )  reg-notify-chatwork-plugin : Notify reg-suit result to Chatwork channel.
 ( )  reg-notify-github-with-api-plugin : Notify reg-suit result to GHE repository using API
 ( )  reg-notify-gitlab-plugin : Notify reg-suit result to GitLab repository
 ( )  reg-notify-slack-plugin : Notify reg-suit result to Slack channel.

? Working directory of reg-suit. [.reg]
※作業用ディレクトリの名前を入力してください(デフォルト:.reg? Directory contains actual images. [directory_contains_actual_images]
※比較先の画像を格納するディレクトリ名を入力してください(デフォルト:directory_contains_actual_images)

? Threshold, ranges from 0 to 1. Smaller value makes the comparison more sensitive.[0]
※比較判定に用いる閾値を01の間で設定してください。0に近いほど、判定が厳しくなります(デフォルト:0? Update configuration file Yes(デフォルト:Yes)
※設定ファイルを更新しますか?

? Copy sample images to working dir Yes(デフォルト:Yes)
※作業用ディレクトリにサンプル画像を配置しますか?(Yes)

テストの流れについて

今回はこのような流れでテストを進めてみました。

  1. ブラウザ自動操作&スクリーンショット収録コードの作成
    • Node.jsの実行ファイルを作成する
    • PlaywrightにはブラウザでURLへアクセスしたり、スクリーンショットを収録するAPIが用意されているので、対象画面のスクリーンショット収録までを自動化する
    • サンプルコード
      const playwright = require('playwright');
      (async () => {
          for (const browserType of ['chromium', 'firefox', 'webkit']) { // 確認対象のブラウザリスト
              const browser = await playwright[browserType].launch();
              const context = await browser.newContext();
              const page = await context.newPage();
              await page.goto('https://example.com'); // 試験対象ページへアクセス
              await page.screenshot({ path: `example-${browserType}.png` }); // スクリーンショットを収録
              await browser.close(); // ブラウザを閉じる
          }
      })();
      
  2. 修正前のスクリーンショット収録
    • 1で作成したファイルをNode.jsで実行する
  3. リファクタリング実施
  4. 修正後のスクリーンショット収録
    • 1で作成したファイルをNode.jsで実行する
  5. 画像比較&レポート確認
    • 2・4 で収録したファイルを所定のディレクトリへ配置する
    • npx reg-suit runで画像比較を実行する
    • 出力された検証結果レポートを確認するf:id:rakus_matsumoto:20211004162158g:plain

苦労した点

Playwrightのコード作成において、いくつかハマりポイントがありました。

  • iframe内のコンテンツが表示されたら○○する

  • 一部ブラウザで処理途中にタイムアウトが発生する

    • 本件はFirefoxにおいて「画面ポップアップするとタイムアウトが発生して後続処理が実行されない」という問題でしたが、調査を続けるとPlaywrightのバグであることがわかりました。
    • Playwrightは絶賛開発が続いているライブラリなので、バグの改善を待つか、別の実装方法がないかを検討するなど、バグを把握しつつ上手く付き合っていく必要があります。

導入して良かった点

  • 効果について

    • 比較対象として目視によるテストを一部実施し、ビジュアルリグレッションテストとのテスト工数の比較をしてみました。試験導入段階ではありますが、目視テストと比較すると2~3割程度のテスト工数を削減できる見込みです。
    • Playwright APIの慣れや、テストユーティリティに共通処理を肥やしていく等、コードを作りこむほどテスト工数の削減率は向上していくと思います。
  • テストの精度について

    • 目視によるテストの場合は、実施者によってはどうしても精度にバラつきが出てしまいますが、reg-suitで機械的な判定をすることで、毎回同じ精度で比較できるので安心・安全にテストが可能です。
    • また、↑のレポートサンプルのように、見やすい形式でレポート出力されるので、比較結果の確認もスムーズでした。同時に、エビデンスを確保できるのも便利です。



スクリーンショットを安定的に収録できるまでは若干の苦労はありましたが、導入は非常にお手軽なので、ビジュアルリグレッションテストを検討中の方は是非お試しください。


  • エンジニア中途採用サイト
    ラクスでは、エンジニア・デザイナーの中途採用を積極的に行っております!
    ご興味ありましたら是非ご確認をお願いします。
    20210916153018
    https://career-recruit.rakus.co.jp/career_engineer/

  • カジュアル面談お申込みフォーム
    どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。
    以下フォームよりお申込みください。
    forms.gle

  • イベント情報
    会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com

Copyright © RAKUS Co., Ltd. All rights reserved.