Appiumの使い方・コマンドをブラウザテスト自動化サンプルコードで解説【Katalon Studio,Android,Groovy,Java】

前回、Katalon Studioを用いたAppiumの環境構築およびテストスクリプトのサンプルコードを紹介しました。
https://nine-num-98.blogspot.com/2020/04/appium-katalon-01.html

↑の記事に掲載した、Appiumテストスクリプトについて、解説します。

テストスクリプト


import com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords as Mobile
import com.kms.katalon.core.webui.driver.WebMobileDriverFactory as WebMobileDriverFactory

import io.appium.java_client.TouchAction
import io.appium.java_client.android.AndroidDriver as AndroidDriver
import io.appium.java_client.android.AndroidElement as AndroidElement
import io.appium.java_client.touch.offset.ElementOption

//(1)ブラウザアプリを起動
apk_path = "C:\\Users\\Users\\Documents\\Katalon Studio\\App\\chrome.apk"
Mobile.startApplication(apk_path, false)
AndroidDriver driver = WebMobileDriverFactory.getDriver()

//(2)URLバーをタップ
AndroidElement url_bar = driver.findElementById("com.android.chrome:id/url_bar");
TouchAction action = new TouchAction(driver)
action.tap(ElementOption.element(url_bar)).perform();

//(3)URLを入力してページを表示
url = "http://yahoo.co.jp"
url_bar.sendKeys(url + "\\n");

//(4)検証対象の要素が表示されるまで待機
logo_xpath = "//hierarchy/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.view.ViewGroup[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.webkit.WebView[1]/android.view.View[1]/android.view.View[1]/android.view.View[2]/android.view.View[1]/android.view.View[1]"
AndroidElement yahoo_logo = driver.findElementByXPath(logo_xpath)

//(5)要素のテキストを取得
String text =  yahoo_logo.getText();
println(text)

//(6)テキストが期待値と一致するかを検証
assert text == "Yahoo! JAPAN"

//(7)要素有(数)を検証
List elms = driver.findElementsByXPath(logo_xpath)
num_elms = elms.size()
assert num_elms == 1

//(8)要素無を検証
List no_elms = driver.findElementsById("no_element")
num_no_elms = no_elms.size()
assert num_no_elms == 0

//(9)下にスワイプして(7)の要素が無になるか検証
action.longPress(PointOption.point(0, 800)).moveTo(PointOption.point(0, 0)).release().perform()
List elms2 = driver.findElementsByXPath(logo_xpath)
num_elms = elms2.size()
assert num_elms == 0

//(10)ブラウザアプリを終了
Mobile.closeApplication()


スクリプトに登場するAppiumのAPI,コマンドについては、java-client 7.3.0 javadoc (io.appium)ドキュメントの他、以下の本などを参考にしました。


実践 Appium
実践 Appium
posted with amazlet at 19.05.04
Manoj Hans
オライリージャパン
売り上げランキング: 466,285

テストスクリプト解説

Katalon Studio上で書いたGroovy言語のスクリプトですが、Katalon Studioで用意されている標準コマンド・APIは極力使っていません。 最初と最後にある、

Mobile.startApplication(apk_path, false)
AndroidDriver driver = WebMobileDriverFactory.getDriver()

……

Mobile.closeApplication()

の箇所だけです。 Katalon Studioで動かす以上、アプリの起動/終了処理はこれらのコマンドを使わざるを得ません。

AndroidDriver driver = WebMobileDriverFactory.getDriver()

についてですが、これはAppiumで定義されているAPIコマンドを使用するために必要な処理です。「Start Application」実行後に作成されたセッションを、Driverインスタンスとして取得します。 これにはWebMobileDriverFactoryというクラスを使用します。

Katalon Studioの公式ドキュメントにも説明があります。

Retrieve mobile's session | Katalon Docs


さて、Appiumの基本的な使い方ですが、

------------------------------------------------
・Driverインスタンスを生成

・Appium(Android)Elementインスタンスの定義

・TouchActionインスタンスの定義

・Driver/TouchActionインスタンスのメソッドを使って、各種操作
------------------------------------------------

のような流れに大体まとまると思います。ここで出てくるインスタンスの元となるクラスは、以下のドキュメントに掲載されています。

https://javadoc.io/doc/io.appium/java-client/latest/index.html

Driverインスタンスについては、先に述べたとおりです。次はこのDriverインスタンスを使って、 デバイス上の画面要素を取得したり、タップ等の操作を実行させたりできます。

例えば (2)URLバーをタップ の処理

//(2)URLバーをタップ
AndroidElement url_bar = driver.findElementById("com.android.chrome:id/url_bar");
TouchAction action = new TouchAction(driver)
action.tap(ElementOption.element(url_bar)).perform();

では、まずAndroidDriver の findElementById メソッドを使用して要素を取得しています。このメソッドに与える引数は、要素を特定する識別子であるリソースIDです。

ここでは「com.android.chrome:id/url_bar"」というURLバーを特定するリソースIDを与えています。 このIDは、Katalon Studioに備わっている要素解析ツール「Spy Mobile Utility」(PCブラウザでいうとうころの DOMインスペクタモード機能?)を用いて、事前に調べておきます。

findElementById で返ってきた要素の情報は、AndroidElementオブジェクトとして定義した、url_bar に格納されています。

このurl_barに対し、タップ操作を行うわけですが、このタップ操作を扱うためのクラスが「TouchAction」です。 これは、driverを引数にしてインスタンス化を行い、tapメソッドを実行することでタップ操作を命令できます。

TouchAction action = new TouchAction(driver)
action.tap(ElementOption.element(url_bar)).perform();

tapメソッドの引数は、単純にElementオブジェクトを入れるのではなく、「ElementOption.element()」というオプション書式をつけたうえで、 操作したいElementを指定する必要があります。さらに、perform()メソッドを最後につなげることで、タップ実行となります。

次の処理ですが、

//(3)URLを入力してページを表示
url = "http://yahoo.co.jp"
url_bar.sendKeys(url + "\\n");

ここは、AndroidElement クラスが持っている sendKeys メソッドに「URL + 改行」を渡しています。 これでURLバーにyahooのURLを入力して、ページ移動ができます。 普段はURLを入力した後、Enterキーを押すとおもいますが、Enterキーの代わりをしているのが「"\\n"」の改行エスケープシーケンスです。

//(4)検証対象の要素が表示されるまで待機
logo_xpath = "//hierarchy/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.view.ViewGroup[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.webkit.WebView[1]/android.view.View[1]/android.view.View[1]/android.view.View[2]/android.view.View[1]/android.view.View[1]"
AndroidElement yahoo_logo = driver.findElementByXPath(logo_xpath)

ここは、検証対象の要素であるyahooのロゴマークの要素を取得する処理です。



Webページの要素と同じく、Androidの画面要素はXPathというパスで特定できます。 要素のXPathも、先に述べた「Spy Mobile Utility」を使って確認できます。

//(5)要素のテキストを取得
String text =  yahoo_logo.getText();
println(text)

取得した要素に対し、AndroidElementで定義されているgetText()メソッドで、テキストを取得しています。

//(6)テキストが期待値と一致するかを検証
assert text == "Yahoo! JAPAN"

取得した要素のテキストに対し、期待値「Yahoo! JAPAN」と一致するかを検証しています。 Groovyのassert機能を使用しています。

5. if文 - Apache Groovyチュートリアル

ここでは、要素のテキストが

・「Yahoo! JAPAN」であればOK
・上記以外("Yahoo!JAPAN" など途中の空白が抜けている等)であればNG

となり、NGであれば期待値と具体的にどこが一致していないかをログに出力してくれます。


また、要素のテキストの検証以外にも、そもそも要素の有無を確認したい、あるいは要素の数を検証したいという場合もあると思います。要素の有無の検証においては、Selenium IDE等にあるような「VerifyElementPresent」がAppiumのコマンドには無いようです。

一つの方法として、以下のようにdriverのfindElements(findElementではありません。複数形です。)メソッドを用いて、要素数をカウントして検証する方法があります。

//(7)要素有(数)を検証
List elms = driver.findElementsByXPath(logo_xpath)
num_elms = elms.size()
assert num_elms == 1

要素数が1の時はOK、それ以外はNGとなります。AndroidElementを1つ以上格納できるListを定義し、size()メソッドで取得できるリスト長の値を検証に利用しています。

逆に、要素が存在しないことを検証(VerifyElementNotPresent)したい場合は、以下のように記述します。

//(8)要素無を検証
List no_elms = driver.findElementsById("no_element")
num_no_elms = no_elms.size()
assert num_no_elms == 0

リスト長が0かどうかをassert文で検証します。0ならばOK、そうでなければNGになります。

次ですが、ちょっと踏み込んで、スワイプ操作を入れて画面スクロールさせて要素検証するというのをやっています。

//(9)下にスワイプして(7)の要素が無になるか検証
action.longPress(PointOption.point(0, 800)).moveTo(PointOption.point(0, 0)).release().perform()
List elms2 = driver.findElementsByXPath(logo_xpath)
num_elms = elms2.size()
assert num_elms == 0

下にスワイプ操作させて(7)で確認した要素が画面外(要素無)になるかを検証しています。

スワイプ操作は、TouchActionクラスのlongPress,moveTo,releaseの各メソッドをチェインして、performで実行という要領で実現できます。longPressとmoveToに与えている、PointOption.point()は、スワイプ移動の始点(longPress)、終点(moveTo)の位置を表しています。

PointOption.point()の中に指定している座標は、画面左上を(0, 0)としています。そこから(右方向,下方向)に向かう値(おそらくピクセル値)で、画面上の位置を指定します。
ここでは、(0, 800)から(0, 0)へ移動させるということですから、下方向に800スクロール(スワイプ)させるということになります。



以上、Appiumのテストスクリプトの説明でした。 Katalon Studioの標準コマンドを使えば、もっと直感的にテストケースを実装できるのですがね…

ですがKatalon Studioの標準コマンドでは手が届かず、AppiumコマンドAPIを使う必要が出てくるかもしれません。その際、Driver, Appium(Android)Element, TouchAction, findElement などのAppiumクラスやメソッドの基本知識があるといいかなと。

参考になれば幸いです。

スポンサーリンク