RegressionテストによるWebデザイン崩れの防止E2E明けましておめでとうございます。エンジニアブログを初めて、ちょうど1年になりました。去年はなんとか月に1記事が書ける程度でしたが、今年は月に最低5記事は書いていきます。Regressionテスト」について紹介します。Regressionテストとは私自身は馴染みのない言葉でしたが、以下のサイト等を見ると「Webページのスクリーンショットを以前のバージョンと比べて、ピクセルレベルでの差分を検出するテスト手法」と定義されているようです。WPJHTML,CSSの修正では、予期せぬ部分に影響することがよくあると思います。それを防ぐために手動によるテストだけに頼ると、サイトの規模が大きくなるにつれてコストが増加しますし、軽微な差であれば目視では気づけ無いこともあります。Regressionテストは、低コストで確実に差分を検出することが可能です。以下のような目視では気づきにくい微妙な差も、スクリーンショットを比較すれば明確に分かります。Regressionテストの実装は、PhantomCSSやBackstopJSを利用すると比較的容易です。techblog.lclco.com上記の記事の通り、弊社も以前はBackstopJSを利用していましたが、後述の確認レポート等を作成するために、使い慣れたRubyを中心とした以下の技術を用いています。S3スクリーンショットの保存PostgreSQLテスト結果の保存テストの流れテストの流れは下記のようになっており、担当者はHubotに命令と、実行結果の確認だけすれば良いだけです。実装担当者が、結果を確認する各所について、補足していきます。テスト実行のタイミング当初、GitへのPUSHをトリガーに自動でテストを実行していましたが、WIP段階でのPUSHや、関係のないサーバサイドの修正でもテストが実行され、チャットへの通知が煩雑になりました。現在は、以下のタイミングで実行しています。Hubotに実行命令を出す)Staging環境へのデプロイ時には自動実行テスト対象ページ予期しないページへの影響を検出するのが、目的の一つであるため、全てのページをテスト対象にするべきと考えてます。(検索ページなどパターンが多すぎるページは、代表ページのみに絞る)弊社では、GoogleスプレッドシートでサイトのURL一覧を管理しており、そのシートをからにテスト対象URLを取得しています。新しいページを作成する場合は、このシートをメンテナンスする運用にしているため、シートに追加すれば自動的にテスト対象に加わるようになっています。Regressionテストでは、何を正として比較するのが重要であり、比較対象は以下の条件が必要と考えています。比較元は、正しい仕様が実装されている比較元と比較先は、同一のデータソースを元にページが生成される。(動的ページの場合は、データソースを同じにしなければ、データによる差異が大量に発生してしまいます)弊社では、実行されるタイミングによって、比較対象を変更しています。開発中の実行時は、現在のブランチの環境*1とStaging環境を比較Stagingのデプロイ時の実行時は、前回のStaging環境での実行結果とデプロイ後のStaging環境の実行結果を比較テスト対象となる全ての環境は、同一のデータベースを参照しており、Staging環境はProduction環境と同じmasterブランチのコードで動いています。これは、masterブランチのコードは正しい仕様であるという前提に立っています。一度masterに不具合が混入した場合、気づかなければ今後も間違い続けるという問題を抱えており、それをガードする仕組みは現在も検討中です。スクリーンショットの差分比較スクリーンショットの取得は、poltergeistのsave_screenshotを利用しています。Capybaraスクリーンショットの差分比較は、Rmagickのcompositeを利用しています。比較元・比較先の画像から、差分画像が作成されます。Magick::DifferenceCompositeOp)差分画像は、黒のピクセルが一致、黒以外が不一致箇所として生成されます。differenceメソッドで差異の数値を求めることも可能です。戻り値の結果が0でなければ差異ありと判断しています。Regressionテストでは、発生した差分が適切かどうかの最終チェックは目視になってしまうため、できるだけ簡単に結果が確認できる仕組みが重要だと考えてます。弊社では、テスト結果をS3,DBに保存し、Web上で一覧表示できるようにしています。)また、ページごとの差分値も表示し、デフォルトは差分なしの画像は表示されません。担当者は、チャットに通知された確認用のURLを開いて、差分がある画像をさっと結果を確認するだけでチェックが完了します。最後に、実装する上でのTIPSをいくつかご紹介いたします。Ajaxの実行完了を待つAjaxを利用して非同期でページを組み立てている場合は、全てのAjaxの完了を待ってスクリーンショットを取得する必要があります。jQueryを利用している場合は、以下のようにjQueryの実行完了までwaitさせるとAjax実行後の画面が取得できます。selectorを記載すると該当箇所のスクリーンショットが取得できます。'#id').動的な広告を除外するページ上に動的な広告を表示していると、アクセスするたびに表示される広告が異なり、毎回差分として検出されてしまいます。1.10から追加されたホワイトリスト・ブラックリスト機能で、広告が配信されるシステムのドメインを除去することで、この問題の対策ができます。弊社では、ホワイトリストに自ドメインと外部JS・画像配信で利用しているいくつかのCDNを追加しています。["テスト対象ドメイン","xxx"]また、余計なファイルのロードも抑制できることで、テスト時間の短縮につながります。Regressionテストを運用してから、テスト工数の削減ができ、何よりも安心してリリースができるようになりました。リファクタリングをする際に有用で、思い切ったリファクタリングに取り組めるようになりました。Regressionテストは、一度仕組みを作ってしまえば、あまり運用コストもかからず、一定の品質担保に役立ちます。本記事が、皆様の参考に少しでもなれば幸いです。*1:ブランチをPUSHすると、テストサーバにそのブランチ専用の環境を生成するようにしています。これについては別途記事を書きたいと思います。2018に参加してきました!モバイルエンジニアの山下です。2018に参...2018-06-22CSSのコンパイラをsass-railsからnode-sassへ変更しましたフロントエンドエンジニアの岡田です。先日、LCLが運営する夜...2018-04-30Zeplinを導入してデザイナーとエンジニアの連携をもっとスムーズにフロントエンドエンジニアの岡田です。1検索はてなブログをはじめよう!lcl-engineerさんは、はてなブログを使っています。ブログを報告する引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。