WebDriver
Selenium
テスト自動化
KatalonStudio
Materials

Katalon Studio+MaterialsでWebサイトのスクリーンショットを整然と保存する

はじめに

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

Katalon Studioを使いはじめて真っ先にやったのがWebサイトのページのスクリーンショットを片っ端から撮ることでした。やってみてわかった。WebDriverでスクリーンショットを撮ることは簡単。しかしファイルを整理整頓するのがえらく面倒だということ。さてどうしたものかとあれこれ解決を試みてはや9ヶ月。やっと解決方法を見いだすことができました。

なおこの記事は GitHub上のレポジトリ UsingMaterialsInKatalonStudio のREADMEを日本語で書きなおしたものです。

概要

わたしは'Materials'というプロジェクトを開発しGitHubで公開しました。このプロジェクトはGroovy言語で書かれておりjarファイルを作り出します。jarファイル の名前は Materials-x.x.x.jar です。Releasesページからjarをダウンロードできます。このjarファイルはKatalon Studio に組み込んで利用することを想定しています。

Katalon StudioのテストスクリプトがWebサイトのスクリーンショットを撮り画像ファイルとしてローカルディスクに保存する時に、保存先ファイルのパスを決定する処理と出来たファイルの一覧HTMLを出力する処理をMaterialsライブラリに任せることができます。そのやり方をこの記事で説明します。

具体的なサンプルコードがGitHubの UsingMaterialsInKatalonStudio にあります。これはKatalon Studioのプロジェクトです。ReleasesページからZIPファイルを自分のPCにダウンロードして解凍し、Katalon Studioを立ち上げてプロジェクトを開いてください。そして下記の説明を読みながらテストケースやテストスイートを実行してみてください。

解決したい問題

わたしが 'material'(素材)と呼んでいるモノが何かというと、テストスクリプトが実行時に作り出したファイルのことです。たとえばWebDriverのAPIを使って撮ったWebページのスクリーンショットとか。その他にもサイトからダウンロードしたPDFファイル、テストスクリプトが生成したExcelファイル、RESTful APIが応答したXML/JSONをファイルに保存すればそれもmaterialのうちです。

Katalon StudioのテストスクリプトはSelenium WebDriverを利用してWebサイトから情報を取り出すことができます。取り出した情報をファイルをして保存したい。しかしどこに保存すればいいのか?この問題をWebDriverは解決してくれません。テストスクリプトの作者がそれぞれにファイルのPathを決めなければなりません。

その場かぎりのファイルのPathを指定するのはどおってことありません。たとえば C:\Users\myname\tmp\sample_screenshot.png とすればいいでしょう。ところが何十個ものファイルを作り、出来たmaterialを再利用したいならことはそう単純ではありません。たとえば自分のWebサイトのスクリーンショットを30枚撮って、本番環境と開発環境とそれぞれについて撮ろう。撮った後で見比べてどこか見た目違っているところがないか探し出したい。

「見比べる」という処理を実現するには比べるべきファイル2つを適切なPathに位置付けておくことが重要です。つまりmaterialのPathの形式を決めることが必要で、かつ、materialのレポジトリ(集合体)へのアクセスを実現したユーティリティ的なライブラリがほしい。

解決方法

Materialsライブラリは com.kazurayam.materials.MaterialRepository オブジェクトを提供します。Katalon StudioのテストスクリプトがMaterialRepositoryオブジェクトのメソッドをcallしてmaterialのPathを決めさせることができます。Pathの形式では下記の通りです。

${projectDir}/Materials/${testSuiteName}/${testSuiteTimestamp}/${testCaseName}/${subdirs}/${fileName}

たとえば

C:\Users\myname\project\Materials\TS07_visit_a_web_site\20180919_132138\TC07_visit_a_web_site\1 CURA_Homepage.png

Windowsのエクスプローラーで Materials フォルダを見るとたとえば下記のようなファイル・ツリーを見ることができます。

TSC10_marked.png

また テストスクリプトが com.kazurayam.materials.MaterialRepositorymakeIndex() メソッドをcallすれば ${projectDir}/Materials/index.html ファイルが作られます。このHTMLファイルはMaterialフォルダの内容を表示するビューワーで、リンクをクリックするだけの簡便な操作でファイルを開いて見ることができます。index.htmlをブラウザで開いた様子を下記に示します。

index.html screen shot in modal
index.png index_modal.png

準備

GitHubの UsingMaterialsInKatalonStudio のソースのZIPをRelease ページからダウンロードすることができます。

このプロジェクトは Materials のjarファイルに依存するのですが実は${projectDir}/Drivers/Materials-0.18.0.jar がすでに組み込んであります。

サンプルコードの説明

UsingMaterialsInKatalonStudioプロジェクトに含まれるテストスクリプトについて順をおって説明します。

Test Cases/TC01_starter

ここでは、スクリーンショットをファイルに出力するにあたってテストスクリプトがPathを具体的な文字列によって指定する方法を説明します。

ソース

TC01_starterを参照のこと

テストケースを実行する

Katalon Studioでプロジェクトを開き Test Cases/TC01_starger を開いてrunボタンを押します。
run_TC01.png

出力

TC01_starterを実行すると下記のようにファイルが出力されます。

$ cd UsingMaterialsInKatalonStudio/
$ tree tmp
tmp
└── TC01_screenshot.png

テストケースの説明

このテストケースはWebページ http://demoaut.katalon.com をブラウザで開いてスクリーンショットを撮り、PNG画像を ${UsingMaterialsInKatalonStudio}/tmp/TC01_screenshot.png ファイルにWRITEします。

TC01_starterのなかの下記の行を見ればわかるように、出力先であるファイルのPathを明示的に指定しなければなりません:

Path pngFile = tmpDir.resolve('TC01_screenshot.png')
WebUI.takeScreenshot(pngFile.toFile().toString())

見てのとおり TC01_starter スクリプトはMaterialsライブラリを使っていません。このスクリプトは出発点です。ここから先、少しずつコードを書きかえていきます。Materialsの使い方を順を追って説明していきます。

テストケース TC01_starter を実行するとプロジェクトのディレクトリ直下に新しいディレクトリが作られます。すなわち: UsingMaterialsInKatalonStudio/tmp です。このディレクトリの中身をKatalon StudioのGUIのなかで閲覧することは残念ながらできません。別のGUIツールを使って見るしかありません。Windowsなら Explorer、MacならFinderないしはTerminalとか EmacsとかvimとかAtomとか。

TC01_starterスクリプトはJava 8のライブラリ java.nio.Pathjava.nio.Pathsjava.nio.Filesを多用します。java.io.Fileは使いません。 Java 8 でファイルのPathを扱うには java.nio.file.* が王道です。

Test Cases/TC02_MaterialRepository

ここでは、com.kazurayam.materials.MaterialRepository オブジェクトを使ってスクリーンショットのファイルのPathを決めるという方法を説明します。

ソース

TC02_MaterialsRepository を参照のこと

抜粋

import com.kazurayam.materials.MaterialRepository
import com.kazurayam.materials.MaterialRepositoryFactory
// descide in which directory we will create a MaterialRepository
Path materialsDir = Paths.get(RunConfiguration.getProjectDir()).resolve('Materials')

// create an instance of MaterialRepository
MaterialRepository mr = MaterialRepositoryFactory.createInstance(materialsDir)

// resolve the location of PNG file to save the screenshot
Path pngFile = mr.resolveMaterialPath('TC02_MaterialRepository', 'TC02_screenshot.png')

// take a screenshot of the page
WebUI.takeScreenshot(pngFile.toFile().toString())

説明

テストケース TC02_MaterialRepository はWebページ http://demoaut.katalon.com のスクリーンショットを撮り、ファイルに出力します。ファイルは ${UsingMaterialsInKatalonStudio}/Materials ディレクトリの下に出力されます。ファイルのパスは ${UsingMaterialsInKatalonStudio}/Materials/_/_/TC02_MaterialRepository/TC02_screenshot.png というふうになります。.

抜粋されたテストケースのコードのなかで resolveMaterialPath(String testCaseName, String fileName) が呼び出されています。このメソッド呼び出しがmaterialのPathを決定します。Pathが決定されると同時に長さゼロのファイルが作成されます。そのあとで WebUI.takeScreenshot(pngFile.toFile().toString()) が実行されることにより、Webページのスクリーンショット画像がファイルに出力されます。

テストケースを実行する

Katalon StudioのGUIを起動し Test Cases/TC02_MaterialRepository を開いて実行ボタンrun_button.PNGを押します。

出力

テストケースを実行すると下記のようなフォルダツリーが生成されます。

$ cd UsingMaterialsInKatalonStudio
$ tree Materials
Materials
└── _
    └── _
        └── TC02_MaterialRepository
            └── TC02_screenshot.png

ここで Materials/_/_/ というフォルダが作られました。ここでアンダーバー '_' という妙な名前のフォルダが作られたのは何故か?といぶかる人がいるでしょう。後述する Test Suites/TS06_GlobalVariable.MATERIAL_REPOSITORY の場合には Materials/TS06_GlobalVariable.MATERIAL_REPOSITORY/20180918_164113 というフォルダが作られます。つまり最初のアンダーバーはテストスイート名に対応し、二番目のアンダーバーはテストスイートが実行された時刻に対応します。ところKatalon StudioのGUIからテストケースを選んで実行した場合にはテストスート名もテストスイート実行時刻も不定になりますので、その場合はフォルダ名にアンダーバーが採用されます。

Test Cases/TC03_subdirectories_under_testCaseName

ここでは、スクリーンショットのファイルを任意のサブディレクトリを作ってその下に格納するという方法を説明します。

ソース

TC03_subdirectories_under_testCaseName を参照のこと。

抜粋

書き方その1

Path pngFile = mr.resolveMaterialPath('TC03_subdirectories_under_testCaseName', 'subdirA/subdirA/TC03_screenshot.png')

書き方その2

// make one more file
pngFile = mr.resolveMaterialPath('TC03_subdirectories_under_testCaseName', Paths.get('subdirB/subdirB'), 'TC03_screenshot.png')

説明

MaterialRepository オブジェクトの resolveMaterialPath() メソッドをcallするときに第2引数として指定した文字列に subdirA/subdirB/ という文字列が指定されていることに注意。これはサブディレクトリを表します。このように指定すればファイルをサブディレクトリの下に格納することができます。

書き方その2を参照。resolveMaterialPath()メソッドにはもうひとつ書き方があります。つまり resolveMaterialPath(String testCaseName, Path subdirs, String fileName) という書き方。どちらもOKです。

テストケースを実行する

Katalon Studio の GUI を起動してテストケース TC03_subdirectories_under_testCaseName を開きます。そして実行ボタンrun_button.PNGを押します。

出力

テストケースを実行すると下記のようなフォルダツリーが出力されます。

$ cd UsingMaterialsInKatalonStudio
$ tree Materials
Materials
└── _
    └── _
        └── TC03_subdirectories_under_testCaseName
            ├── subdirA
            │   └── subdirA
            │       └── TC03_screenshot.png
            └── subdirB
                └── subdirB
                    └── TC03_screenshot.png

テストケース名 TC03_subdirectories_under_testCaseName と同じ名前のフォルダの下に subdirA/subdirA とか subdirB/subdirB といったサブフォルダが作られていることに着目してください。

Test Cases/TC04_URL-based_filename

ここでは、スクリーンショットのファイル名をWebページのURLに基づいて決定するという方法を説明します。

ソース

TC04_URL-based_filename

抜粋

String urlString = 'http://demoaut.katalon.com'
...
File pngFile = mr.resolveScreenshotPath('TC04_URL-based_filename', new URL(urlString))
...
pngFile = mr.resolveScreenshotPath('TC04_URL-based_filename', Paths.get('subdir'), new URL(urlString))

テストケースの説明

Webページのスクリーンショットを撮ったあとファイルに保存するときどういうファイル名にしようか?たとえば 'sample1.png' とか 'demoX.png' でももちろんかまわない。しかしいちいちファイル名を案出するのが面倒ならば、WebページのURLをそのままファイル名にしてしまうのが一番簡単です。

com.kazurayam.materials.MaterialRepository オブジェクトは resolveScreenshotPath(String testCaseName, URL url)resolveScreenshotPath(String testCaseName, Path subdir, URL url) というメソッドも提供します。メソッド呼び出し引数に java.net.URL が含まれていることに注意。このURLに基づいてファイル名が導出されます。URLに含まれる特殊文字は URLエンコードされてファイル名としてふさわしい文字に変換されます。たとえば

http://demoaut.katalon.com/ --> http%3A%2F%2Fdemoaut.katalon.com%2F

というふうに。

出力

テストケース TC04_URL-based_filename を実行すると下記のようなツリーが出力されます。

$ cd UsingMaterialsInKatalonStudio
$ tree Materials
Materials
└── _
    └── _
        └── TC04_URL-based_filename
            ├── http%3A%2F%2Fdemoaut.katalon.com.png
            └── subdir
                └── http%3A%2F%2Fdemoaut.katalon.com.png

Test Cases/TC05_GlobalVariable.CURRENT_TESTCASE_ID

テストケースのコードが自分自身の名前を参照したい場合があります。たとえば resolveMaterialPath() メソッドが第一引数としてテストケース名を指定しなければならない、とか。ところがKatalon Studioではテストケース名を簡単に調べる方法が無くて、少しまわり回りくどいコードを書かねばなりません。その答えをここで紹介します。

ソース

MyTestListenerTC05_GlobalVariable.CURRENT_TESTCASE_ID を参照のこと。

説明

まず、Katalon StudioのGUIでProfiles>defaultを選択して、CURRENT_TESTCASE_ID という名前の GlobalVariable を定義します。データ型はString、初期値は '' としましょう。
Profile_default_CURRENT_TESTCASE_ID.PNG

つぎにテストリスナー MyTestListerner を作ります。@BeforeTestCase でアノテートしたメソッドを作ります。ここで「いまのTest Caseの名前」を取り出して GlobalVariable.CURRENT_TESTCASE_ID に設定します。

@BeforeTestCase
def beforeTestCase(TestCaseContext testCaseContext) {
    GlobalVariable.CURRENT_TESTCASE_ID = testCaseContext.getTestCaseId()

いっぽうテストケース TC05_GlobalVariable.CURRENT_TESTCASE_ID はGlobalVariableを参照してテストケース名を認識します。

String testCaseId = (String)GlobalVariable.CURRENT_TESTCASE_ID
assert testCaseId != null
assert testCaseId.length() > 0
Path pngFile = mr.resolveMaterialPath(testCaseId, 'TC05_screenshot.png')

前述のテストケース 'TC02_MaterialRepository' ではテストケース名を文字列定数としてハードコードしていましたが、GlobalVariableを利用したこのコーディング手法を用いればテストケース名をハードコードする必要が無くなります。

出力

テストケース TC05_GlobalVariable.CURRENT_TESTCASE_ID を実行すれば下記のようなツリーが出力されます。

$ cd UsingMaterialsInKatalonStudio
$ tree Materials
Materials
└── _
    └── _
        └── TC05_GlobalVariable.CURRENT_TESTCASE_ID
            └── TC05_screenshot.png

Test Suites/TS06_GlobalVariable.MATERIAL_REPOSITORY

ここまでは、com.kazurayam.materials.MaterialRepositoryオブジェクトをテストケースの冒頭で生成しテストケースの終了とともに破棄していました。しかしテストスイート TS06_GlobalVariable.MATERIAL_REPOSITORY ではテストリスナーが com.kazurayam.materials.MaterialRepository オブジェクトを生成してGlobalVariableに保存し、テストケースがGlobalVariableを参照するというやり方を導入します。これによってcom.kazurayam.materials.MaterialRepository オブジェクトを生成するコードをテストケース群のあちこちに散らかすのではなく、TestListener一箇所に集約することができます。全体としてコードが短くなり、読みやすくメンテナンスしやすくなります。

ソース

GlobalVariable として MATERIAL_REPOSITORY を定義します。 GlobalVariable.MATERIAL_REPOSITORY.PNG

ここで注意。 MATERIAL_REPOSITORY の型として Null を指定します。GUI上は Null という名前を選択しますが、Groovyソースコードを見ると MATERIAL_REPOSITORY 変数が java.lang.Object 型のオブジェクトとして宣言されることがわかります。MATERIAL_REPOSITORY をStringなど他の型で宣言してはいけません。

テストリスナー Test Listeners/MyTestListener.groovy を見ましょう。ここで com.kazurayam.materials.MaterialRepository オブジェクトを生成し、GlobalVariable.MATERIAL_REPOSITORY に格納します。

@BeforeTestSuite とアノテーションされたメソッドでこうします:

@BeforeTestSuite
def beforeTestSuite(TestSuiteContext testSuiteContext) {
    // prepare instance of MaterialRepository
    // The directory 'Materials' will be created if not present by the MaterialRepository
    MaterialRepository mr = MaterialRepositoryFactory.createInstance(materialsDir)

    // Find out the Test Suite ID
    String testSuiteId = testSuiteContext.getTestSuiteId()

    // Find out the Test Suite Timestamp
    Path reportDir = Paths.get(RunConfiguration.getReportFolder())
    String testSuiteTimestamp = reportDir.getFileName().toString()
    // e.g. '20180618_165141'

    // inform the MaterialRespository of the current Test Suite
    mr.putCurrentTestSuite(testSuiteId, testSuiteTimestamp)

    // save the instance into GlobalVariable so that it is visible
    // for all test cases activated by the Test Suite
    GlobalVariable.MATERIAL_REPOSITORY = mr

次の一行があやしげです:

mr.putCurrentTestSuite(testSuiteId, testSuiteTimestamp)

これが何をやっているかはあとで「出力」の節で説明します。

もう一箇所 @BeforeTestCase とアノテートされたメソッドでこうします:

@BeforeTestCase
def beforeTestCase(TestCaseContext testCaseContext) {
    ...
    // prepare an instance of MaterialRepository
    // The directory 'Materials' will be created if not present by the MaterialRepository
    // This is necessary for the case a Test Case is executed directly without being wrapped by a Test Suite.
    if (GlobalVariable.MATERIAL_REPOSITORY == null) {
        // If wrapped by a Test Suite, the handler method annotated with @BeforeTest suite will be called
        // and it will instantiate a MaterialRepository and store it into GlobalVariable. Therefore
        // we check if the GlobalVariable is null or not. We will instantiate new one
        // only when the GlobalVariable is null.
        MaterialRepository mr = MaterialRepositoryFactory.createInstance(materialsDir)
        GlobalVariable.MATERIAL_REPOSITORY = mr
    }
}

テストリスナーによって GlobalVariable.MATERIAL_REPOSITORYcom.kazurayam.materials.MaterialRepository オブジェクトが格納されました。

いっぽうでテストケース TC06_GlobalVariable.MATERIAL_REPOSITORY がGlobalVaribleを参照します。下記のように:

MaterialRepository mr = (MaterialRepository)GlobalVariable.MATERIAL_REPOSITORY
assert mr != null
...
Path pngFile = mr.resolveMaterialPath(testCaseId, 'TC06_screenshot.png')

テストケース TC06_GlobalVariable.MATERIAL_REPOSITORYTC07_visiting_a_web_siteTC08_makeIndex --- これらはもはや com.kazurayam.materials.MaterialRepository オブジェクトを自分で作成しません。そのかわりテストリスナー MyTestListener が作成し、テストケースはGlobalVariablを参照する、というやり方をとっています。

テストスイートの実行の仕方

Katalon Studioでテストスイートを実行するには下記の操作をします。

  1. Katalon StudioのGUIでテストスイート TS06_GlobalVariable.MATERIAL_REPOSITORY を開きます。
  2. runボタン(ツールバーのなかの緑矢印)を押します TS06.png

出力

テストスイート TS06_GlobalVariable.MATERIAL_REPOSITORY を実行すると下記のようなツリーが出力されます。

$ cd UsingMaterialsInKatalonStudio
$ tree Materials
Materials
└─TS06_GlobalVariable.MATERIAL_REPOSITORY
    └─20180918_164113
        └─TC06_GlobalVariable.MATERIAL_REPOSITORY
                TC06_screenshot.png

ここで注目。TS06_GlobalVariable.MATERIAL_REPOSITORY というディレクトリと 20180918_164113 というディレクトリが作られている。テストスイート名と実行時タイムスタンプにほかなりません。タイムスタンプの書式は yyyyMMdd_hhmmss です。テストスイートが二度実行されれば別別のタイムスタンプになりますからディレクトリが2つ別別に作られます。

このタイムスタンプの値がどうやって決定されるのか?じつは テストリスナーMyTestListener の @BeforeTestSuite とアノテートされたメソッドのなかで com.kazurayam.materials.MaterialRepository オブジェクトに対してテストスイート名とタイムスタンプ値を教えていました。下記の一行がそれです:

    mr.putCurrentTestSuite(testSuiteId, testSuiteTimestamp)

タイムスタンプにもとづくディレクトリの階層があるので、過去にテストスイートが実行された時に生成されたすべてのmaterialsを時系列に保存されます。こうして過去分のテストスイートの実行結果を再利用することが可能になります。

このようなディレクトリツリーの構造はKatalon Studioの Reports ディレクトリの構造を真似したものです。
Reports.PNG

Test Suites/TS07_visit_a_web_site

テストスイート TS07_visit_a_web_sitehttp://demoaut.katalon.com/ を入り口とするWebサイトを訪問してスクリーンショットを5つ作成します。PNGファイルのPathは下記のような形式をとります。

./Materials/TS07_visit_a_web_site/yyyyMMdd_hhmmss/TC07_visit_a_web_site/fileName.png

実際にWebサイトを訪問するコードはテストケース TC07_visit_a_web_site に書いてあります。このテストケースはKatalon StudioでひとつのWebサイトを巡ってスクリーンショットを撮る操作の実例となるものです。

出力

テストスイート TS07_visit_a_web_site を実行すると下記のようなツリーが出力されます。

$ cd UsingMaterialsInKatalonStudio
$ tree Materials
Materials
└─TS07_visit_a_web_site
    ├─20180919_132138
    │  └─TC07_visit_a_web_site
    │          1 CURA_Homepage.png
    │          2 CURA_Login.png
    │          3 CURA_Appointment.png
    │          4 CURA_AppointmentConfirmation.png
    │          5 CURA_Homepage_revisited.png
    │          
    └─20180919_132139
        └─TC07_visit_a_web_site
                1 CURA_Homepage.png
                2 CURA_Login.png
                3 CURA_Appointment.png
                4 CURA_AppointmentConfirmation.png
                5 CURA_Homepage_revisited.png

テストスイートのタイムスタンプにもとづいて2つのディレクトリができ、各々のなかに5つのスクリーンショットが保存されていることに注目してください。

Test Suites/TS08_makeIndex

com.kazurayam.materials.MaterialRepository オブジェクトの makeIndex() メソッドをcallすれば ./Materials/index.html ファイルが生成されます。materialファイルの一覧画面です。

ソース

TC08_makeIndex を参照のこと。

抜粋

MaterialRepository mr = (MaterialRepository)GlobalVariable.MATERIAL_REPOSITORY

// make ./Material/index.html file
mr.makeIndex()

これだけです。

出力

テストスイート TS08_makeIndex を実行すると下記のようなツリーが出力されます。

$ cd UsingMaterialsInKatalonStudio
$ tree Materials
Materials
│  index.html
│  
└─TS07_visit_a_web_site
    ├─20180919_132139
    │  └─TC07_visit_a_web_site
    │          1 CURA_Homepage.png
    │          2 CURA_Login.png
    │          3 CURA_Appointment.png
    │          4 CURA_AppointmentConfirmation.png
    │          5 CURA_Homepage_revisited.png
    │          
    └─20180919_135957
        └─TC07_visit_a_web_site
                1 CURA_Homepage.png
                2 CURA_Login.png
                3 CURA_Appointment.png
                4 CURA_AppointmentConfirmation.png
                5 CURA_Homepage_revisited.png

Webブラウザで index.html ファイルを開いてください。Materialsフォルダの下のファイルツリーをそのままHTMLで表現しています。このHTMLはbootstrap-treeviewでスタイルづけされています。
Materials_index.png

上記の画面例ではテストスイートに対応するバーが2つあってそれぞれ 'production' と 'development' とラベルづけされています。このラベルはテストスイートを実行するときに適用された Execution Profile の名前です。

上記の画面例のなかで、テストケースに対応するバーが2つあってそれぞれに PASSED とか FAILURE と表示されています。ここで各テストケースが実行されたときに成功したか失敗したかの区別を表示しています。

ひとつひとつのmaterialに対応するバーがあって、ファイル名がリンクになっています。それをクリックすると画像ファイルがモダールなダイアログのなかに表示されます。
Materials_index_modal.png

Test Suite Collections/TSC09_visit_a_web_site_and_make_index

テストスイートコレクションとは何かについてはKatalonのドキュメント Test Suite Collectionを参照のこと

説明

そろそろ大詰めです。テストスイートコレクション TSC09_visit_a_web_site_and_make_index を見てみましょう。これは下記3つのテストスイートを順番に実行します。

  1. TS00_clearMaterials --- <project>/Materials ディレクトリの内容を削除して空にします
  2. TS07_visit_a_web_site --- Webサイトを訪問してスクリーンショットを撮ります
  3. TS08_makeIndex --- <project>/Materials/index.html を作成します。

テストスイートコレクション TSC09_visit_a_web_site_and_make_index ではテストスイートを実行するときにExecution Profile として default を指定します。
TSC09.png

テストスイートコレクションを実行するやり方

テストスイートコレクションを選択し開いた状態で画面のなかをみると How_to_run_TSC09.PNG Execute というボタンがあります。このボタンをクリックするとテストスイートコレクションが実行されます。テストケースやテストスイートを実行するときに使うボタン run_button.PNG とは別のボタンなので混同しないよう注意すること。

テストスイートコレクション実行時のログを見る方法

テストスイートコレクションは複数のテストスイートをまとめていっぺんに実行するための概念です。テストスイートコレクションを実行したとき、当然ながら、個々のテストスイートの実行ログを閲覧したくなるでしょう。ところがKatalon StudioのGUIはちょっと不親切なデザインになっていて、ログをどうやってみればいいのかわかりにくくなっています。説明を補います。テストスイートコレクションを実行したとき画面右下に目玉のような形のアイコンが表示されます。下記の画面キャプチャを参照のこと。この目玉アイコンをクリックするとドロップダウンリストが表示され、そのなかに実行されたテストスイートが列挙されます。マウスでひとつを選ぶと当該テストスイートの実行時ログを検索し表示することができます。ちょっと回りくどいですが。
How_to_retrieve_testsuite_log_in_testsuitescollection.png

Test Suite Collections/TSC10_visit_2_environments

説明

テストスイートコレクション TSC10_visit_2_environments はテストスイート TS07_visit_a_web_site を2度実行します。まず production という名前のProfileを指定して実行し、次に development という名前のProfileを指定して実行します。
TSC10_2_profiles.png

入力

プロファイルには GlobalVariable.Hostname が定義してあります。GlobalVariable.HostnameはテストスクリプトがアクセスすべきURLのホスト名部分です。だからプロファイルを切り替えることで本番環境と開発環境と二つの環境を同じテストスクリプトでテストするができます。

Production Development
GlobalVariable.Hostname=http://demoaut.katalon.com/ demoaut.katalon.com.png GlobalVariable.Hostname=http://demoaut-mimic.kazurayam.com/ demoaut-mimic.kazurayam.com.png

二つの画像を見比べれば少しだけ違っていることがわかります。

出力

テストスイートコレクション TSC10_visit_2_environments を実行すると ./Materials/index.html ファイルができます。
TSC10_index.PNG

この画面の中で TS07_visit_a_web_site のバーが2つあって、それぞれにプロファイル名(developmentproduction)が表示されていることに注目してください。同じテストスイートを2つの環境に向けて2度実行した結果が区別できます。

補足

本記事は 'Materials' をKatalon StudioでWeb画面のスクリーンショットを撮ってファイルに保存するのに使うことを説明しました。Materialsのjarはこれ以外の用途にも応用できます。

スクリーンショット以外のファイルも扱えること

com.kazurayam.materials.MaterialRepositor オブジェクト resolveMaterialPath() メソッドは java.nio.file.Path をリターンします。つまりMaterialsライブラリはファイルの中身が何であるかを気にしません。だからスクリーンショットを画像ファイルに保存するだけでなく、WebサイトからダウンロードしてきたPDFファイルを./Materialsフォルダの中に格納するとか、Excelファイルをテスト実行時に動的に作製してMaterialsフォルダの中に格納するとか、RESTful APIが応答したXML/JSONを./Materialsフォルダに保存といった用途につかうことができます。

Katalon Studio以外のテスティングフレームワークとも組み合わせられること

Materials-x.x.x.jar は Java8 とくに java.nio.file.*slf4j に依存しますが、それだけです。Katalon StudioのAPI には全く依存していません。だから Materialsを 他のテスティング・フレーム(ただしJVMで動くもの)と組み合わせることができます。たとえば JUnit とか Spock とか。

まとめ

Webアプリの本番環境と開発環境のスクリーンショット2組を撮りファイルに出力することができました。次に同じ画面のPNGファイル2つを取り出して比較することをしてみたくなります。次回は Visual Testing を Katalon Studio でやってみました、を報告します。