はじめに
わたしはWebアプリケーションのUIをテストとする作業をソフトウェアで自動化する技術に関心があります。2018年1月以来わたしは Katalon Studio というソフトウェアに注目しています。「Katalon Studioとはどんなソフトウエアか」で概要を紹介しました。
Webシステムの本番環境の画面と開発環境の画面を見比べて大きな違いがあったらテストがfailする、あるいは本番環境の入れ替え作業の前と後の画面を見比べて大きな違いがあったらテストがfailする、そういう自動化テストをKatalon Studioで実現しました。この自動化テストを本記事で紹介します。
以下の文章はGitHubレポジトリ VisualTestingInKatalonStudio のREADMEとほぼ同じ内容を日本語で書き直したものです。
解決すべき問題
Katalon Studioで Visual Testing を実現したい。Visual Testingとは何か?画面確認の作業を自動化することです。
下記のようなことをわたしは実現したいとおもっていて、それを実現する手法のことをVisual Testingと呼ぶことにしました。
- わたしはブラウザで某Webサイトを見に行く。しょっちゅう見に行く。わたしはそのWebの開発者かもしれない、デザイナかもしれない、テスト担当者かもしれないし、ただのファンかもしれない。
- そのWebサイトのページをできるだけ多く目で見て確認したい。システムになんらか不具合が発生した時どこに顕在化するか予測できない。だからひとつふたつページを選んで見るのでは駄目。広く目配りすることが重要。
- Webページ全体のスクリーンショットを撮ってファイルに保存したい。証拠(evidence)として残したい。
- Webサイトの本番環境と開発環境と2つの環境の画面を目で見比べるように、2つの環境のスクリーンショット画像に差異があるかどうかをチェックしたい。
- Webサイトの本番環境で入れ替え作業前に画面のスクリーンショットをとっておき、作業後にもう一度とって、前後を見比べたい。
- 画面の食い違いの大きさを数値化したい
- 一連の作業を自動実行したい
Webサイトに100ページもあったらスクリーンショットを撮るのにどれぐらい時間がかかるでしょうか。人手でやったら1時間以上かかるだろう。しんどくて退屈な作業だ。そんな奴隷労働なんかやりたくない。でも会社からやれといわれてやらざるをえない場合がある。そんな時のためにツールを開発して画面確認作業を自動化しよう。
わたしはVisual Testingツールが2つの環境の画面を見比べて重大な差異があればそれに気づかせてくれることだけを望んでいます。Visual Testingツールに本格的なデバッグ機能を求めない。ただし無償で利用可能であってほしい。
Katalon Studioでテスト・スクリプトを書き始めてすぐ以下の課題に気づきました。
(1) 画像ファイルを整理整頓するのが面倒だという課題
わたしは本番環境と開発環境と2つの環境のスクリーンショットをたくさん撮ってローカルディスクにいったん保存し、あとで再利用したいと考えた。あるスクリプトがファイルのPathを決めてWRITEする。べつのスクリプトがファイルのPathを発見してREADする。そうするためにはスクリーンショットのファイルのPathをどうするか仕様を決めて2つのスクリプトがその仕様に基づいて動作するようにしなければならない。技術的に高度ではないが面倒くさいコードを書く必要がありました。
(2) ページ全体のスクリーンショットが撮れないという課題
Selenium WebDriverのAPIに org.openqa.selenium.TakesScreenshot#getScreenshotAs(output)
がある。これを使えばWebページのスクリーンショットを撮ることができる。しかし実際にやってみると目に見えている部分(View Port)だけが撮影されるが、画面全体のスクリーンショットを取ることができない。これでは不十分だ。
(3) ふたつの画像を比較したいという課題
開発環境のWebページのスクリーンショットをとり、本番環境のスクリーンショットをとってPNG画像ファイルにすることはできたが、それだけでは不十分だ。二つのPNG画像を見比べてどの部分が食い違っているのかがすぐわかるようにしたい。人が2つの画像を見比べて些細な食い違いを見いだすのは甚だ困難だから。また食い違い部分の面積と画面全体の面積の比率 diff ratio を数値として求めたい。diff ratioが0.00なら2つの画像は完全に同じ、0.12ならちょっと違うところがある、70.45なら甚だ大きな違いがある、といえる。画面の見た目の違いをdiff ratioという数値で語れるようにしたい。
解決方法
(1) ファイルのPathにかんする課題の解決
この問題を解決するためにわたしは下記のGroovyライブラリを開発しました。
Materials-X.X.X.jarをKatalon Studioに組み込んで使います。Katalon Studioのプロジェクトのディレクトリに Materials
ディレクトリを作り、その下に整理整頓されたファイル・ツリーを構築します。そしてファイルにアクセスするためのメソッドを提供します。
Materials-X.X.X.jarの使い方を紹介するのが下記:
- UsingMaterialsInKatalonStudio --- サンプルとして動くKatalon Project
UsingMaterialsInKatalonStudioプロジェクトはあるWebサイトの2つの環境にアクセスしてスクリーンショットをたくさん撮りPNGファイルにしてローカルディスクに保存したうえでそれらを一覧するHTMLを生成します。REAMDE(英文)を日本語で書き直したのが下記です:
(2) ページ全体のスクリーンショットの解決
この問題をaShot が解決してくれました。aShotをKatalon Studioで使ってみようとデモを作成し下記のGitHubレポジトリにアップしまし。
(3) ふたつの画像ファイル比較の解決
aShot の ImageDiff
が解決してくれました。
aShotをKatalon Studioのなかで使得るよう、わたしはもうひとつKatalon Studioプロジェクトを作ってGitHubで公開しました。
このプロジェクトのなかにはカスタム・キーワード com.kazurayam.ksbackyard.ScreenshotDriver
が含まれています。Materialsディレクトリのなかから比較すべきファイルのリストを取り出したり、2つの画像ファイルの隔たりの大きさを示す数値を算出するなどのメソッドを備えています。
これらの外部リソースを統合して VisualTestingInKatalonStudio
プロジェクトを仕上げました。これは冒頭わたしが「Visual Testingとはこういうもの」と述べた要件を満たすものになっています。
ツールが出力したレポートのサンプル
某日、VisualTestingInKatalonStudioプロジェクトのTest Suites/CURA/Execute_twinsを実行して作成されたindex.htmlをネットにアップロードしたサンプルがあります。こんな結果レポートが最終的に得られます。
VisualTestingInKatalonStudioのサンプルコードを動かす方法
ダウンロードサイト
Releases ページにZIPファイルが公開されています。これをダウンロードして解凍してください。
前提するKatalon Studioのバージョン
2020年1月現在で最新バージョンであるKatalon Studio ver7.2.1を使うことを前提して以下説明を記述します。ただしVisualTestingInKaztalonStudioプロジェクトはもともとKatalon Studio ver5.6で開発されました。その後のバージョンアップにも影響されないことを検証済みです。
TwinsモードとChronosモード
VisualTestingInKatalonStudioプロジェクトは2018年秋に最初のバージョンがリリースされました。初期バージョンでは、あるWebシステムの本番環境と開発環境(つまり2つ別々のURL)を大体同じタイミングでスクリーンショットして比較するという方法を実装しました。これを Twinsモード と名付けました。Twinsとは「双子 ふたご」のことです。テスト対象のWebシステムがすでに安定的に本番稼働している一方で開発環境で開発作業を進めている時に、開発環境のWebページが本番環境と比べてどう変化しているかを目視する作業 --- 開発者は毎日何度もこれを繰り返すでしょう --- を省力化するのに役立ちます。あるいは共通モジュールやDBのデータを変更した時それが画面上に及ぼす影響を広く目視確認しようという場合に役立ちます。
2019年春にもう一つの機能を追加しました。あるWebシステムの1つのURLのスクリーンショットを時間的に前後させて都合2回取得して出来た画像群を比較する。これを Chronosモード と名付けました。Chronosとは「時間」のこと。Webサービスの本番環境でソフトウェアの入れ替えや環境設定の修正などの作業を行う場合に、作業前と作業後の2度にタイミングを分けてスクリーンショットを取得し、できたスクリーンショット画像を比較する作業を自動化することができます。スクリーンショットを100個取得するようなテストコードを事前に準備しておいて作業当日に実行しましょう。あなたがコーヒーを飲んでいる10分ほどの間にKatalon Studioがスクリーンショット採取と画像比較をしてくれます。最後に生成されたindexページをみれば本番環境での作業が満足できるものであったかどうか証跡に基づいて判定することができるでしょう。
Twinsモードのサンプルを実行する手順
-
Katalon Studioを起動し、
VisualTestingInKatalonStudio
プロジェクトを開く - Tests ExplorerペインのなかにTest Suitesアイコンがあるのを選びます。その下にサブフォルダ
CURA
があります。さらにその下にCURA/Execute_twins
がある。このアイコンをダブルクリックして開く。CURA/Execute_twins
はテストスイートコレクションです。CURA
はテスト対象であるWebサイトのシンボルです。 -
CURA/Execute_twins
はFirefoxブラウザがあなたのPCにインストール済みで使用可能であることを暗黙に前提している。もしなかったらFirefoxをインストールしてください。 - テストスイートコレクション
CURA/Execute_twins
の定義画面の中に緑色の矢印つきでExecute
というボタンがあるのでそれを押して実行します。 - テストが走り終わるまでに2分ぐらいかかります。
-
VisualTestingInKatalonStudio/Materials/index.html
というファイルができます。これをWebブラウザで開いて見てください。
Katalon Studioの古いバージョンでは <projectDir>/Materials
ディレクトリとそのなかのファイルをKatalon StudioのGUIのなかで見ることができませんでした。しかし2019年5月にリリースされたver6.1.5以降なら可能です。Katalon StudioのGUIツールバーで Project > Reflesh を実行してプロジェクトを再読み込みしてください。<projectDir>/Materials/index.html
をダブルクリックすればWebブラウザが起動されてindex.htmlを見ることができます。
デモ CURA/Execute_twins
の説明
テストスイートコレクション CURA/Execute_twins
が何をするのか、概要を説明します。
入力
テストスイートコレクション CURA/Execute_twins
はテストスイート Test Suites/CURA/twins_capture
を二度実行します。最初は本番環境に向けて。二度目は開発環境に向けて。下記ふたつのURLにアクセスします。
- http://demoaut.katalon.com/ --- Production すなわち本番環境
- http://demoaut-mimic.kazurayam.com/ --- Development すなわち開発環境
処理内容
テストスイート Test Suites/CURA/twins_capture
は指定されたURLを訪問し、順番にページをたどってスクリーンショットを撮ります。./Materials/CURA.twins_capture/yyyyMMdd_hhmmss/CURA.visitSite
というディレクトリが作られて中にPNGファイルが5つ保存されます。
続いてテストスイートコレクション CURA/Execute_twins
はテストスイート CURA/twins_exam
を実行します。テストスイート CURA/twins_exam
はPNGファイル群を読み同じ画面どおし比較して、差分画像を生成します。生成した差分画像を ./Materials/CURA.twins_exam/yyyyMMdd_hhmmss/CURA.ImageDiff_twins/CURA.visiteSite
というディレクトリに保存します。
比較された2つの画面に差異があれば差分画像のなかに下記のような赤く塗られた領域ができます。ひと目見れば「あれ、なんか違っているぞ!」とわかりますね。
下記がシーケンス図です。
差分画像のファイル名の形式
差分画像ファイルのファイル名は下記のようなフォーマットに従います。例をあげますと:
home(48.71)FAILED.png
ファイル名の最初の部分 home
は比較の元になったファイル名 home.png
からコピった名前です。
差分ファイルのファイル名の末尾にある (48.71)
をわたしは diff ratioないしdiff% と呼びますが、定義は
diff % := number of RED pixcels(differences) / (width * hight of page) * 100
です。つまり画面全体の広さを100としたときに赤く塗られた差分領域の広さがどれだけあるかを示すパーセンテージです。本番環境と開発環境とが完璧に一致していれば diff% は 0.00 ですが、diff%が0より大きい値になることがしばしばです。
差分ファイルのファイル名の末尾に FAILED
という文字があったり無かったりします。FAILED
のマークの有無がどうやって決まるか?それを理解するには Test Cases/CURA/ImageDiff_twins
のコードを見る必要があります。すなわち:
import com.kazurayam.visualtesting.ImageDiffer
String TESTSUITE_ID = 'cURA/twins_capture'
double criteriaPercentage = 1.0
ImageDiffer imageDiffer = new ImageDiffer()
boolean result = imageDiffer.runTwins(TESTSUITE_ID, criteriaPercentage)
runTwins()メソッド呼び出しの第2引数に 1.00
という数値が指定されています。これをわたしは criteria% と呼びます。criteriaとは「目安」のこと。差分画像のdiff%が48.71ならばcriteria%の1.00より大きい、だからこの差分は重要であると判断されて、FAILED
とマークがつけられます。FAILED
したら要注意です。
出力
某日作成されたindex.htmlをネットにアップロードしたサンプルがあります。
FAILED
とマークされた差分画像ファイルのバーの背景色が紫色で強調表示されることに注意。ただしdiff%の数値が0.12とかでcriteria%の数値(たとえば1.00)より小さければその差分は重要でないとみなされFAILEDマークがつきません。だからindex画面上も強調表示されません。
強調表示された home(48.71)FAILED.png
をクリックするとダイアログが開き、その中に差分画像が表示されます。赤い領域が大きいのにちょっと驚きます。
ダイアログの左辺ないし右辺をクリックすると画像がスライドして下記のような表示に切り替わります。
左に本番環境の画面のスクリーンショット、右に開発環境の画面のスクリーンショットが並べて表示されます。二つをチラチラ見比べるとどこがどう違っているから赤く表示されたのか理由がわかります。
Chronosモードのサンプルを実行する手順
-
Katalon Studioを起動し、
VisualTestingInKatalonStudio
プロジェクトを開く - Tests ExplorerペインのなかにTest Suitesアイコンがあるのを選びます。その下にサブフォルダ
CURA
があります。さらにその下にCURA/Execute_chronos
がある。このアイコンをダブルクリックして開く。 -
CURA/Execute_chronos
はFirefoxブラウザがあなたのPCにインストール済みで使用可能であることを暗黙に前提している。もしなかったらFirefoxをインストールしてください。 - テストスイートコレクション
CURA/Execute_chronos
の定義画面の中に緑色の矢印つきでExecute
というボタンがあるのでそれを押して実行します。 - テストが走り終わるまでに1分ぐらいかかります。
-
CURA/Excecute_chronos
を初めて実行した時には(あまり褒められた仕様ではない --- 実装の手落ち --- のですが)GroovyコードがExceptionを投げてエラー終了します。これは理由があってのこと。気を撮り直してもう一度CURA/Excecute_chronos
を実行してください。 -
VisualTestingInKatalonStudio/Materials/index.html
というファイルができます。これをWebブラウザで開いて見てください。
デモ CURA/Execute_chronos
の説明
テストスイートコレクション CURA/Execute_chronos
がどのように動作するか、下記に説明します。
入力
テストスイートコレクションは CURA/Execute_chronos
下記のURL にアクセスしてスクリーンショットを取得します。
CURA/Execute_chronos
は今回取得したスクリーンショット画像を <projectDir>/Storage
ディレクトリへ保管します。こんな風に。
CURA/Execute_chronos
は実行されると <projectDir>/Storage
ディレクトリに保管された過去
のスクリーンショット画像の中から適切なものを選択します。選択された過去のスクリーンショット画像を <projectDir>/Materials
フォルダにコピーします。これによりMaterialsフォルダの下に「前の画像」と「今の画像」が揃います。二つの画像群を比較して差分をとりレポートを出力するしくみは CURA/Execute_twins
と同じです。
処理内容
CURA/Execute_chronos
を2回実行します。本番環境でする作業の前に一度。そして作業完了後にもう一度。そうすることで前後の比較が可能になります。
CURA/Execute_chronos
が<projectDir>/Storage
のなかから比較対象となる「過去の画像」を選択する時、どういう基準で選ぶのでしょうか?それは
に記述しています。例えば
WebUI.callTestCase(findTestCase("Test Cases/VT/restorePreviousTSuiteResult"),
["STRATEGY":"last"])
STRATEGY:lastがデフォルトですが、lastすなわち「前回」です。今回の一回前に CURA/Execute_chronos
が実行された時に保管されたスクリーンショット画像群が選択されます。今回が何月何日何時何分何秒であってもそれは関係なくて、今回より一つ前です。
他にも選択の仕方があります。
WebUI.callTestCase(findTestCase("Test Cases/VT/restorePreviousTSuiteResult"),
["STRATEGY":"exactlyAtOrBefore", "timestamp":"20191205_110904" ])
STRATEGY:exactlyAtOrBeforeはtimestampとして指定された年月日時分秒に一致する記録が有ればそれを、無ければそれより前の一番近いやつを選びます。
他にどんなSTRATEGYが選択可能なのか?
Test Cases/VT/restorePreviousTSuiteResultのソースをみてください。
出力
テストスイートコレクション CURA/Execute_chronos
はCURA/Execute_twins
とまったく同じく <projectDir>/Materials/index.html
を出力します。
外部依存性について
外部jarへの依存性
VisualTestingInKatalonStudio
プロジェクトは下記のjarファイルに依存しています。
2つのjarが <projectDir>/Drivers/
のなかにあらかじめ組み込んであります。
外部のjarをKatalon Studioに組み込む方法がドキュメント "External Libraries" で説明されています。この操作をしてMaterialsやaShotをアップグレードすることができます。
カスタム・キーワードの依存性
VisualTestingInKatalonStudio
プロジェクトは下記の外部プロジェクトで開発されたCustom Keywordのソースコードをimportして再利用しています。
ksbackyardプロジェクトの Releases ページから ksbackyard-all.jar
ファイルをダウンロードすることができます。このjarをKatalonプロジェクトのDriversディレクトリに放りこむことで参照可能になります。
あなたのWebサイトにVisual Testingを応用するにはどうすればいいか
VisualTestingInKatalonStudioのサンプルは http://demoaut.katalon.com
というURLを対象としています。しかしあなたがテストしたいURLはこれではないですよね。あなたがテストしたいURLに対してVisual Testingの方法を適用するにはどうすればいいのでしょうか? ーーー それを可能にする方法を開発しました。別記事「あなたのWebサイトをVisual Testingする方法」で説明します。