Katalon Studio + aShotでスクリーンショットを撮る

# はじめに

わたしはWebアプリケーションのUIをテストとする作業をソフトウェアで自動化する技術に関心があります。2018年1月以来わたしは [Katalon Studio](https://www.katalon.com/) というソフトウェアに注目しています。以前「Katalon Studioとはどんなソフトウエアか」で概要を紹介しました。

Webアプリの管理・運用を任務としている人がKatalon StudioのようなWebアプリケーションのテスト自動化ツールで実現したいことといえば、なによりも画面のスクリーンショットをとる手間を省力化することではないでしょうか？本番運用中のWebサービスが健全であることを確認するために画面50個のスクリーンショットをとりたい。手作業でやったら1時間以上かかる。毎日こんなことやれない！ --- そうですよねえ。Katalon Studioでスクリーンショット取得のルーチンワークを自動化することができます。今回はこのテーマについてわたしが実際に試したことの一部を報告します。

# 関連する記事

本記事はあなたがKatalon Studioをすでに手元にダウンロードして使い方に慣れていることを前提し、スクリーンショットをどう取ってどう利用するかという論点について述べます。Katalon Studioの始め方については下記のQiita記事を参照してください。

1. [Katalon Studioをインストールした](https://qiita.com/kazurayam/items/135cb30233d11c2f4840)
2. [Katalon StudioでRecordしてみた](https://qiita.com/kazurayam/items/433876c0b3bc7f33f019)
3. [Katalon Studioでテストを自作した](https://qiita.com/kazurayam/items/bdf71ed70fdc32bb1758)
4. [Katalon Studioでテストを自作した（２）](https://qiita.com/kazurayam/items/29282b749def80a806de)

# サンプルプロジェクト

本記事の内容を実装したKatalon Studioプロジェクトを下記URLで公開しています。

- https://github.com/kazurayam/EntirePageScreenshotByAShotInKatalonStudio


# Katalon Studioによる自動的なスクリーンショット取得

Test Suiteによって間接的に起動されたTest CaseがFAILした時、Katalon Studioはブラウザに表示されていた画面のスクリーンショットを自動的に取得し、`<projectディレクトリ>\Reports\<test suite名>\<yyyyMMdd_hhmmss>` ディレクトリのなかに保存します。そして `<projectディレクトリ>\Reports\<test suite名>\<yyyyMMdd_hhmmss>\Reports.html` ファイルがスクリーンショット画像を参照します。テストがなぜFAILしたのか理由を知るための補足情報として画像を利用しています。

### サンプル

[EntirePageScreenshotByAShotInKatalonStudio](https://github.com/kazurayam/EntirePageScreenshotByAShotInKatalonStudio)プロジェクトのTest Suite `TS1_screenshot_taken_when_failed` を実行してください。このTest SuiteはTest Case [`TC1_screenshot_taken_when_failed`](https://github.com/kazurayam/EntirePageScreenshotByAShotInKatalonStudio/blob/master/Scripts/TC1_screenshot_taken_when_failed/Script1535938329763.groovy) を実行するのですが、このTest CaseはかならずFAILします。 `EntirePageScreenshotByAShotInKatalonStudio\Reports\TS1_screenshot_taken_when_failed\<yyyyMMdd_hhmmss>\Reports.html` というHTMLファイルが生成されるのですが、それを開くと下記のように結果レポートのなかにスクリーンショットが埋め込まれて表示されます。

![TS1_screenshot_taken_when_failed.PNG](https://qiita-image-store.s3.amazonaws.com/0/52995/7c48c0e2-50dd-1083-1028-b0883617f5e3.png)

ちなみにテスターがKatalon Studioにたいして画像取得の有無を設定するまでもなく、Katalon Studioはデフォルトでこのように動作します。

# takeScreenshotメソッドでスクリーンショットをとる

Katalon Studioの標準機能のなかに [WebUI.takeScreenshot(String filepath)](https://docs.katalon.com/display/KD/%5BWebUI%5D+Take+Screenshot) があります。ソースコードが非公開なので確実なことはいえませんが、おそらく単純にWebDriverのメソッドを呼び出すことでスクリーンショットを取得するメソッドであるとおもわれます。ちなみにWebDriverのメソッドでとったスクリーンショットがいろいろ問題含みであることは知る人ぞ知るところです。たとえば下記のURLを参照。

- [Seleniumで撮ったスクリーンショットがブラウザごとにばらばら問題](https://qiita.com/meganetaaan/items/b11338d2867c8c8f072a)

標準機能のtakeScreenshotメソッドでスクリーンショットをとったらどうなるか？サンプルを作りました。

### サンプル


[EntirePageScreenshotByAShotInKatalonStudio](https://github.com/kazurayam/EntirePageScreenshotByAShotInKatalonStudio)プロジェクトのTest Suite [`TC2_screenshot_taken_when_failed`](https://github.com/kazurayam/EntirePageScreenshotByAShotInKatalonStudio/blob/master/Scripts/TC2_viewport_only_screenshot/Script1535941446259.groovy) を実行してください。Firefoxブラウザを選択しましょう。テストケースが動くとブラウザが幅375x高さ667と小さめのウインドウで開いてスクリーンショットが撮影され、`<project dir>\Screenshots\TC2_viewport_only_screenshot.png` というファイルができます。このPNGファイルはこんな感じ：

![TS2_viewport_only_screenshot.png](https://qiita-image-store.s3.amazonaws.com/0/52995/6cd5fab7-078b-50ea-c977-68789a80f2f7.png)

じつはこのスクリーンショットは不完全です。縦方向にはみ出した領域があって、それが画像に含まれていません。はみでた領域というのはこんなものでした：

![TS2_viewport_only_screenshot_dropped_part.png](https://qiita-image-store.s3.amazonaws.com/0/52995/7ee661e0-936a-b054-f775-e2f561dcce8d.png)

不完全なスクリーンショット画像は役に立ちません。改善が必要です。

# aShotでページ全体のスクリーンショットをとる

下記の記事が改善の方法を教えてくれました。

- [【pom+5行で解決】Selenium WebDriverでブラウザを問わずページ全体のスクリーンショットを撮影する](https://qiita.com/hainet/items/423732f075d523f06d25)

Katalon Studioに[aShot](https://github.com/yandex-qatools/ashot) を組み込んで、Webページ全体のスクリーンショットをとることに成功しました。

Katalon Studioのドキュメント[External Libraries](https://docs.katalon.com/display/KD/External+Libraries) を一読願います。任意のjarファイルをKatalon Studioに登録して、Test Case実行時に参照可能にすることができます。サンプルプロジェクトには aShot のver1.5.4が登録ずみです。

### サンプル

[EntirePageScreenshotByAShotInKatalonStudio](https://github.com/kazurayam/EntirePageScreenshotByAShotInKatalonStudio)プロジェクトのTest Case [`TC3_whole_page_screenshot`](https://github.com/kazurayam/EntirePageScreenshotByAShotInKatalonStudio/blob/master/Scripts/TC3_whole_page_screenshot/Script1535947171445.groovy) を実行してください。テストケースが動くとブラウザが幅375x高さ667と小さめのウインドウで開いてスクリーンショットが撮影され、`<project dir>\Screenshots\TC3_whole_page_screenshot.png` というファイルができます。できた画像は下記のようにページ全体を含んだものになっています。これなら良い。

![TC3_whole_page_screenshot.png](https://qiita-image-store.s3.amazonaws.com/0/52995/f8b55710-0c13-da19-91fe-4ea73f82cd4c.png)


# aShotで二つの画像を比較して差分を検出する

aShotにはScreenshot comparison(スクリーンショットを比較する)という素敵な機能が備わっています。この機能をKatalon Studioのなかで動かしてみましょう。


### サンプル

[EntirePageScreenshotByAShotInKatalonStudio](https://github.com/kazurayam/EntirePageScreenshotByAShotInKatalonStudio)プロジェクトのTest Case [`TC4_imageDiffer`](https://github.com/kazurayam/EntirePageScreenshotByAShotInKatalonStudio/blob/master/Scripts/TC4_imageDiffer/Script1535956206390.groovy) を実行してください。テストケースが動くと `<project dir>\Screenshots\TC4_imageDiffer(6.32).png` というファイルができます。

![TC4_imageDiff(6.32).png](https://qiita-image-store.s3.amazonaws.com/0/52995/bb651bf4-dca4-e867-91a0-5ac216c3a939.png)

赤く塗られた箇所があります。これが2つのスクリーンショットを比較して違っていたところです。違いがあることは一目瞭然です。

ファイル名の一部として `(6.32)` という数字を埋め込みました。これをわたしは diff% と呼んでいます。diff%は画面全体の面積にたいして赤い差分箇所の面積がどれだけあるかをTest Caseのなかで計算して得た百分率です。ふたつの画像が完全に一致すればdiff%は0.0です。上記サンプル画像の程度の差異であればdiff%は6.32%であった、というわけです。

Test Case `TC4_imageDiffer` はエイヤで決めた境界値 3.0% を基準とし、diff%が境界値よりも大きければTest CaseをFAILさせています。Webアプリの特性に依存しますが、本番環境と開発環境を見比べるとわずかではあるが差分が生じるのが避けられない場合があります。画面のなかに現在時刻hh:mmが表示されている場合とか。ターゲットとするWebアプリの特性を勘案しながら境界値を適切に選びましょう。予想の範囲内の差異を穏便にスルーしつつ、予想を超える差異が生じたらテストがFAILする、という境界値を見出すことができればナイスですね。

この手法を発展させればあなたのWebアプリの本番環境と開発環境の画面を見比べておかしなところがないかを調べるという（退屈な）作業を自動化する道が開けるでしょう。


# Webサイトのページ全部を比較したいんだけど...

ここまではひとつのページのスクリーンショットを取ることを目標としてKatalon StudioとaShotを動かすサンプルコードを示してきました。ではひとつのWebサイトのページ全部（たとえば100ページとか）を対象に本番環境と開発環境のスクリーンショットを比較したいとおもったとしましょう。どうでしょう、準備OKでしょうか？

準備OKではありません。スクリーンショット画像をファイルとして保存したいがどこに保存するか、保存したファイル群のリストをどうやって取得するか、ある条件にしたがって画像を特定して読み込みたいがそのファイル・パスをどうやって知るか。こういうファイルの読み書きに関する処理を実現しなければならない。スクリーンショット・ファイルのパスを決定するルールを設計し、ファイルの読み書き探索を集約的に実装したライブラリが必要です。さもないとスクリーンショット・ファイルを読み書きするコードがKatalon StudioのTest Caseのあちこちに散在して収拾がつかなくなるでしょう。

また、100個200個とたくさんのファイルができるので、それらを一覧表示するインデックスがほしくなります。一覧の中のリンクをクリックすれば個々のスクリーンショット画像がダイアログで表示されるようにしたい。HTML+CSS+JavaScriptをよろしく駆使して好ましいユーザインタフェースを実現したい。システムを運用管理する現場で使うツールを作るならUIの使いやすさをおろそかにできません。

わたしはKatalon Studioで取得したスクリーンショット・ファイルを生前と管理しインデックスを生成してくれるライブラリ `Materials` を開発しました。[Katalon Studio+MaterialsでWebサイトのスクリーンショットを整然と保存する](https://qiita.com/kazurayam/items/6d76148fa866129696b7)でMaterialsライブラリについて述べました。

aShotとMaterialsがあれば、Webサイトのページ全部のスクリーンショットをとること、本番環境と開発環境を比較すること、これを自動化することができます。[](https://qiita.com/kazurayam/items/bcf72a03f50fc5db4373)で応用例を紹介しました。