ローソンデジタルイノベーション テックブログ

ローソンデジタルイノベーション(LDI)の技術ブログです

Shiratesを使ってAndroidをセットアップする(2)- 自動入力サービスの無効化を自動化する

ども。LDI品質管理部の仙波です。 スマホアプリの自動テストを担当しています

前回はAndroidのエミュレーター使ってテストを行う場合に必要となるセットアップを紹介しました。

今回はセットアップタスクの一部を自動化する方法を紹介します。

Shiratesを使用してセットアップを自動化する

Shiratesはローソンデジタルイノベーションが作成したスマホアプリ用の自動テストツールです。 自社で運用していますが、オープンソースソフトウェアとして公開しているのでどなたでも利用できます。

クイックスタートを実施して自動テスト環境を構築しているという前提で以下の説明を行います。

自動入力サービスの無効化を自動化する

以下の手順を自動テストとして実装してみます。

  • 設定アプリを起動します。
  • 下方向にスクロールしてパスワードとアカウントをタップします。
  • 自動入力サービスのアイテムをタップします。
  • なしをタップします。

画面上の要素を指定するロケーターを調べるにはAppium Inspectorを使用します。
(参照 Appium Inspectorを使用する

  • ターミナルを起動してappiumを実行します。
  • Appium Inspectorを起動します。
  • Android 13のエミュレーターを起動します。(前回作成したAVDを使用できます)
  • Desired Capabilitiesタブで下記のように設定してStart Sessionをクリックします。
Name Type Value
appium:automationName Text UiAutomator2
platformName Text Android
appium:platformVersion Text 13
appium:appPackage Text com.android.settings
appium:appActivity Text com.android.settings.Settings
  • タップする要素のロケーターを調べます。

パスワードとアカウント画面においては自動入力サービスの下にあるアイテムをタップしたいですが、この要素には画面内でユニークになる属性がありません。 Googleというテキストは2つ存在するのでユニーク識別子としては使えません。また、android:id/titleというresource-idも画面内に複数存在するので使えません。

Appiumではこのような場合はタップする対象を指定することが困難です。

Shiratesでは相対セレクターを利用してこの問題を解決できます。 以下のように、周辺に存在するユニークな要素からの相対関係で目的の要素を指定することができます。

<自動入力サービス>:belowLabel

手順を表にまとめると以下のようになります。

No アクション セレクター
1 設定アプリを起動する
2 下方向へスクロールしてパスワードとアカウントをタップする パスワードとアカウント
3 自動入力サービスの下のラベルをタップする <自動入力サービス>:belowLabel
4 なしをタップする なし
5 前画面に戻る
6 なしが表示されていることを確認する なし

この手順を自動テストコードとして実装してみます。

プロジェクトの作成

  • IntelliJ IDEAを起動します。
  • File > New > Project を選択します。
  • NameにAndroidSettings1を入力します。その他の項目は画面キャプチャを参考にして設定します。
  • build.gradle.ktsを下記のように編集します。

plugins {
    kotlin("jvm") version "1.8.21"
}

group = "org.example"
version = "1.0-SNAPSHOT"

val shiratesCoreVersion = "4.4.3"

repositories {
    mavenCentral()
}

dependencies {
    testImplementation(kotlin("test"))

    // JUnit 5
    testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.2")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.2")

    // shirates-core
    testImplementation("io.github.ldi-github:shirates-core:$shiratesCoreVersion")

    // https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core
    testImplementation("org.apache.logging.log4j:log4j-core:2.20.0")

    // https://mvnrepository.com/artifact/org.slf4j/slf4j-nop
    testImplementation("org.slf4j:slf4j-nop:2.0.5")
}

tasks.test {
    useJUnitPlatform()
}

kotlin {
    jvmToolchain(17)
}
  • Gradleのリロードボタンをクリックします。

テスト構成ファイルの設定

  • shirates-coreプロジェクトのtemplateフォルダからアイテムをコピーします。
  • testConfig/android/androidSettings/androidSettingsConfig.jsonを下記のように編集します。
{
  "testConfigName": "androidSettingsConfig",

  "appIconName": "設定",

  "packageOrBundleId": "com.android.settings",
  "startupPackageOrBundleId": "com.android.settings",
  "startupActivity": "com.android.settings.Settings",

  "capabilities": {
    "language": "ja",
    "locale": "JP"
  },

  "profiles": [
  ]
}

testrun.global.propertiesの下記の部分を編集します。

  • テストプロファイル(AVD名を設定することでそのAVDを起動できます)

    • android.profile=Pixel 6(Android 13)
  • ログの言語

    • logLanguage=ja

テストクラスの作成

  • src/test/kotlinフォルダ下にSetAutofillServiceという名前でクラスを作成します。
  • 下記内容に編集します。
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Order
import org.junit.jupiter.api.Test
import shirates.core.configuration.Testrun
import shirates.core.testcode.UITest

@Testrun("testConfig/android/androidSettings/testrun.properties")
class SetAutofillService: UITest() {

    @Test
    @Order(10)
    @DisplayName("自動入力サービスを無効にする")
    fun s1(){

        scenario {
            case(1){
                condition {

                }.action { 
                    
                }.expectation { 
                    
                }
            }
        }
    }
}
  • テストコードを右クリックしてDebugを選択します。この時点ではテストで検証を行なっていないので、以下のメッセージが出力されますが問題ありません。
org.opentest4j.TestAbortedException: テスト結果がありません。expectationブロック内でアサーション関数を実行してください。

テストコードの実装

先ほどの表の内容を実装します。

No アクション セレクター
1 設定アプリを起動する
2 下方向へスクロールしてパスワードとアカウントをタップする パスワードとアカウント
3 自動入力サービスの下のラベルをタップする <自動入力サービス>:belowLabel
4 なしをタップする なし
5 前画面に戻る
6 なしが表示されていることを確認する なし
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Order
import org.junit.jupiter.api.Test
import shirates.core.configuration.Testrun
import shirates.core.driver.commandextension.*
import shirates.core.testcode.UITest

@Testrun("testConfig/android/androidSettings/testrun.properties")
class SetAutofillService : UITest() {

    @Test
    @Order(10)
    @DisplayName("自動入力サービスを無効にする")
    fun s1() {

        scenario {
            case(1) {
                condition {
                    it.terminateApp()
                        .launchApp()
                }.action {
                    it.tapWithScrollDown("パスワードとアカウント")
                        .tap("<自動入力サービス>:belowLabel")
                        .tap("なし")
                        .pressBack()
                }.expectation {
                    it.exist("なし")
                }
            }
        }
    }
}

テストコードの実行

  • テストコードを右クリックしてDebugを選択します。
  • テストの実行が正常に完了するとコンソールに以下のように出力されます。
  • リンクをクリックするとフォルダが開きます。
  • Report(Simple)を開きます。

まとめ

Shiratesを使用してAndroidの設定アプリで自動入力サービスを無効にする手順を自動テストとして実装しました。

次回はAndroidの設定アプリでプロキシ設定する手順の自動化方法を紹介します。