シンママQAエンジニア|Appiumで始めるネイティブアプリ自動化

QAエンジニア

モバイルアプリの操作を自動化したいけれど、「ボタンや入力欄をどう指定すればいいの?」と迷ったことはありませんか。
Appiumを使ってネイティブアプリを操作するには、画面の要素を正しく特定することが欠かせません。
そのための基本が「ui.xml」を取得して要素の属性を読み解く方法です。

この記事では、Android端末からui.xmlを取り出して要素を特定する手順と、アプリのパッケージ名やアクティビティ名の調べ方を初心者向けに丁寧に解説します。
これを理解すれば、Appiumでのネイティブアプリ操作の第一歩を安心して踏み出せるはずです。

前提とゴール

対象はWindows環境でAndroid端末を操作するケースです。
ADBが使える状態で、端末はUSBデバッグがオンになっている前提です。
ゴールは、ui.xmlを取得して要素属性を読み取り、実戦的なロケータを設計できるようになることです。


Appiumにおける「要素」とは

テストコードから操作する一つひとつのUI部品のことです。
ボタンや入力欄、テキストなどを指します。
Appiumは画面のUI階層を解析して「要素」を見つけ、タップや入力などの操作を実行します。


ui.xmlとは

端末上の現在表示中の画面を、ツリー構造で表現したXMLです。
各ノードがUI部品を表し、resource-idcontent-desctextclassboundspackage などの属性を持ちます。
この属性を手がかりにロケータを設計します。


ui.xmlの取り方

1.端末を認識させる

adb devices

device と表示されれば接続OKです。

2.調査したいアプリ画面を端末で表示する

調べたい画面を開いた状態にしておきます。

3.UIツリーをダンプしてPCへ取得する

adb shell uiautomator dump /sdcard/ui.xml
adb pull /sdcard/ui.xml .

プロジェクト直下に ui.xml が取得できれば成功です。
もし ERROR: null object などが出たら、画面が点灯しているか、管理者権限の制限がないかを確認します。

4.XMLをエディタで開く

VS Codeやお好みのエディタで ui.xml を開きます。
ノードを上から追い、該当コンポーネントの属性を読み取ります。


ui.xmlの読み方とロケータ設計

XML内の <node .../> が一つのUI部品を表します。
特に以下の属性を優先して使います。

  • resource-id
    例:com.example.app:id/loginButton
    最も安定しやすいIDで、基本はこれを第一候補にします。
  • content-desc
    アクセシビリティ用の説明文です。
    Androidでは「アクセシビリティID」として取得できます。
  • text
    表示文字列です。
    多言語で変わる可能性があるため、多用は避けます。
  • class
    例:android.widget.Button
    型の絞り込みに使います。
  • package
    その要素が属するアプリのパッケージ名です。
    画面混在時の切り分けに役立ちます。

Pythonでの指定例

from appium.webdriver.common.appiumby import AppiumBy

# resource-idを使う例
driver.find_element(AppiumBy.ID, "com.example.app:id/loginButton")

# content-descを使う例
driver.find_element(AppiumBy.ACCESSIBILITY_ID, "ログイン")

# やむを得ずXPathで指定する例(安定性は要注意)
driver.find_element(AppiumBy.XPATH, "//android.widget.Button[@text='ログイン']")

IDやアクセシビリティIDを最優先にし、XPathは最後の手段にするのが実務の定石です。


パッケージ名とアクティビティ名の取得

これは何に使うのか

appPackage と appActivity はAppiumが起動時にどのアプリのどの画面から開始するかを指定するための情報です。
パッケージ名はアプリの一意識別子で、アクティビティ名はアプリ内の画面を表すエントリポイントです。
この二つがわかると、Appiumからアプリをダイレクトに立ち上げられます。

今表示中のアプリから取得する方法

アプリを前面に出した状態で以下を実行します。

adb shell dumpsys window | findstr mCurrentFocus

出力例。

mCurrentFocus=Window{... u0 com.example.app/com.example.MainActivity}

com.example.app がパッケージ名で、com.example.MainActivity がアクティビティ名です。

機種やOSによっては次のコマンドの方が確実です。

adb shell dumpsys activity | findstr mResumedActivity

または。

adb shell dumpsys activity activities | findstr Resumed

APKから取得する方法(APKが手元にある場合)

aapt dump badging app-debug.apk | findstr package
aapt dump badging app-debug.apk | findstr launchable-activity

package と launchable-activity の行から読み取れます。
aapt はAndroid SDKのビルドツールに含まれます。


Appiumの起動指定例(参考)

appPackage と appActivity を使ってアプリを起動します。

from appium import webdriver
from appium.options.android import UiAutomator2Options

caps = {
    "platformName": "Android",
    "appium:automationName": "UiAutomator2",
    "appium:deviceName": "Android Emulator",
    "appium:appPackage": "com.example.app",
    "appium:appActivity": "com.example.MainActivity",
    "appium:noReset": True
}

options = UiAutomator2Options().load_capabilities(caps)
driver = webdriver.Remote("http://127.0.0.1:4723", options=options)

起動後に ui.xml を更新して再取得すれば、目的要素の属性が最新状態で確認できます。


うまくいかない時のチェックリスト

  • adb devices に device が出ていない。
    ケーブルやドライバを確認し、adb kill-server && adb start-server を試します。
  • uiautomator dump が失敗する。
    画面が消灯していないかを確認し、パスに /sdcard/ を含めて再実行します。
  • ui.xml内に目当ての要素が見当たらない。
    WebView内の可能性があります。
    その場合はChrome DevToolsでの要素確認や、コンテキスト切り替えの検討が必要です。
  • XMLの text でロケータを組んだら他言語で落ちる。
    resource-id や content-desc を優先し、文字列依存を避けます。

まとめ

要素特定はui.xmlで属性を読むところから始まります。
resource-id と content-desc を最優先にして、安定したロケータを作ります。
パッケージ名とアクティビティ名を押さえれば、Appiumから狙いどおりにアプリを起動できます。

タイトルとURLをコピーしました