appiumを使ってモバイルアプリのテストを自動化する

こんにちは!SPEEDA プロダクト開発チームの板倉です。
前回は、テスト環境(appium + gauge + kotlin)のセットアップについて書きました。

appiumを使ってモバイルアプリのテストを自動化する ~環境構築まで~ - Uzabase for Engineers

今回は、実際にアプリのテストをどう書くのかについて書いていこうと思います。

テスト対象のアプリ

今回はAndroid StudioでBasic Activityを選択してプロジェクトを作成したアプリを例にテストを書いていきます。

今回はプロジェクト作成時に作られたコードをそのまま使用しています。

テストを書く

Spec, Scenario, Step

まずは、画面表示までScenarioを書いていこうと思います。
アプリを起動すると何が表示されるのかをStepに記述します。

# ホーム画面

## ホーム画面を表示する
* ヘッダにタイトル"example"が表示される
* ヘッダにアクションボタンが表示される
* コンテンツにメッセージ"Hello World!"が表示される
* フローティングアクションボタンが表示される

GaugeのSpecの書き方として、
# は Spec
## はScenario
* はStep
となります。

Stepの実装を書いていく

Stepに記述した文章はアノテーションに記述します。
ダブルクオートで囲んだ部分はパラメータになりますので、メソッドに引数として定義します。
1つ目のStepを例に実装すると以下のような形になります。

@Step("ヘッダにタイトル<title>が表示される")
fun ヘッダにタイトルが表示される(title: String) {
}

メソッドの中に操作や検証を記述していきます。
操作や検証をするにはセレクタを使用して要素を取得して行います。
Specに記載した内容を実装すると以下のようになります。

@Step("ヘッダにタイトル<title>が表示される")
fun ヘッダにタイトルが表示される(title: String) {
  val header = driver.findElementById("toolbar")
  header.findElement(By.className("android.widget.TextView")).text shouldEqual title
}


@Step("ヘッダにアクションボタンが表示される")
fun ヘッダにアクションボタンが表示される() {
    val header = driver.findElementById("toolbar")
    header.findElement(By.className("android.widget.ImageView")).isDisplayed shouldBe true
}

@Step("コンテンツにメッセージ<message>が表示される")
fun コンテンツにメッセージが表示される(message: String) {
    // xpathは避けたほうがいいです。
    // そのままのコードを使ったので、開発する際はidを設定するなど工夫が必要だと思います。
    val content = driver.findElement(By.xpath("//android.widget.FrameLayout/android.view.ViewGroup/android.view.ViewGroup"))
    content.findElement(By.className("android.widget.TextView")).text shouldEqual message
}

@Step("フローティングアクションボタンが表示される")
fun フローティングアクションボタンが表示される() {
    val button = driver.findElementById("fab")
    button.isDisplayed shouldBe true
}

この実装をする上で、ヘッダのタイトルのセレクタを記述する際に困りました。
そういったときに使えるツールを紹介します。

Appium Desktop

AppiumはGUIツールが公開されています。
このツールはインスペクターだけでなく、Appiumサーバーの起動も行えます。

github.com

アプリのダウンロードはこちら

確認してみる

今回困ったヘッダのタイトルの要素を見てみると、

左側に表示しているアプリ上でヘッダのタイトルをクリックすると、中央のAppSourceに表示されたソースから要素がハイライトされ、右側には要素の情報を見ることができます。
今回はツールバーをid指定で取得し、その要素からclassNameを指定して取得するセレクタを使用してタイトルの要素を取得することにしました。

さいごに

AppiumからSelenium Driver(AndroidDriver, IOSDriverなど)が提供されているので、思ってた以上に簡単にテストを書くことができました。
今回試したのはアプリに表示されている要素の取得と検証のみだったので、ネイティブ特有の機能を使う場合どのような実装が必要なのかは調べてみようと思います。

Page top