見出し画像

Appium DesktopでWindowsデスクトップアプリのロケータを採ってみる

こんにちは。SHIFT⾃動化エンジニアの森川です。
本⽇はAppium Desktopを使ってWindowsデスクトップアプリケーションの⾃動テスト⽤のロケータを採る⽅法についてお話します。

実施環境

・ Windows 10
・Appium Desktop v1.15.1
・WinAppDriver v1.1.1
※ Appium Desktop、WinAppDriverともにこれらのバージョン以外では本記事で紹介する動作を期待できません。
Appiumにおいては本記事執筆時点で最新バージョンは1.18.2であり、バージョンの新旧差が⼤きいことをご了承ください。

Windowsアプリの⾃動テストにはWinAppDriverを⽤います。

WinAppDriverとは

WinAppDriverはWindowsのデスクトップアプリケーションを操作するためのツールで、Appiumが提供するDriverの一つというポジションなため既存のAppiumクライアントで動かすことができます。SeleniumのWebDriver等とまったく同じというわけにはいきませんが、共通点が多く、Seleniumに慣れていれば扱いやすいというのが大きな特徴だと思います。 
https://github.com/microsoft/WinAppDriver

要素ロケータの調査

別名「ロケータ探しの旅」とも⾔われ、GUI自動テストエンジニアならば誰でも経験する苦⾏(注:筆者主観)の⼀つです。 Web(またはアプリ)の要素のIDやCSSセレクタといったいわゆるロケータ情報をどうやって取ってくるか。また、保守性を上げるためにロケータの取得ルールはどう定めるべきか。世界中のテスト⾃動化エンジニアが、頭を悩ませてきた課題だと思います。

Windowsアプリの場合、inspectやspy++、またWinAppDriverの開発元がリリースしているUI-Recorder(※1)で取得するのがオーソドックスな手法だと思います。
ですが「inspectでWindowsクラスを追いかけるのはちょっと⾯倒だな。何かもう少し良い⼿はないものかな︖」とも思います。
モバイルアプリだったら、Appium Desktopに接続してレコード&キャプチャできるじゃないか。Windowsアプリでもできないのだろうか︖

ということでやってみました。

準備と実行

テスト⾃動化では「スモール・スタート」がセオリー。ありきたりですが電卓アプリを使って要素ロケータを取得してみることにします。 


まず、該当バージョンのAppium Desktopをインストールします。
https://github.com/appium/appium-desktop/releases
次に、WinAppDriverをインストールします。
https://github.com/microsoft/WinAppDriver/releases

Appium Desktopを起動します。

画像1

「サーバ 〜 を起動する」でAppiumをデフォルト設定で起動して

画像2

メニューで「File - New Session Windows」を選択します。

画像3

セッションウインドウが表⽰されますので
・上部タブでは「⾃動設定」を選択します
・下部タブでは「Desired Capabilities」を選択します
・右下の「Json Representation」でEditアイコンをクリック
・後述のJsonデータを貼りつけます
・保存アイコンをクリックします

※ OSとデバイスにWindowsを指定して、アプリケーションに電卓アプリをAUMIDで指定しています。

{ 
"platformName": "windows", 
"deviceName": "WindowsPC", 
"app": "Microsoft.WindowsCalculator_8wekyb3d8bbwe!App" 
}
画像4

これで準備完了なので「セッションを開始する」をクリックします。
AppiumからWinAppDriverが起動されて、電卓アプリが起動すれば成功です。

画像5

セッションウインドウ上で電卓の要素を選択(⻩⾊にマーク状態)すると、電卓の各要素ロケータを採ることができます。

画像6

セッションウインドウの上部左側の3つのアクション・アイコンは「要素を選択する」を常に選択しておきます。

画像7

「座標でスワイプ」、「座標でタップ」はこのセッション形式(※)ではサポートされていないようです。
※ Appiumクライアント + WinAppDriverによるスワイプやタップは可能だと思われます。

次にAppium Desktopから電卓を制御してみます。
電卓の要素を選択した⻩⾊マーク状態で、右ペインの操作から「Tap」をクリックします。
⼀瞬、ポインタ制御が奪われ、指定した要素に対して電卓アプリが⾃動操作されます。

Appium Desktopには操作の記録(Recorder)とエクスポート機能がありますので、こちらを⽤いて電卓の操作をコード化してみましょう。
試した操作は以下です。
・クリア(C)
・3 x 6 = (18)


記録終了後、エクスポート形式を選択して、コードをクリップボードにコピーします。
筆者はJava環境なので「Java JUnit」を選択しました。

⽣成されたコード

MobileElement el1 = (MobileElement) driver.findElementByXPath("/Window/Window[2]/Group/Group[5]/Button[4]");
el1.click();
MobileElement el2 = (MobileElement) driver.findElementByXPath("/Window/Window[2]/Group/Group[4]/Button[2]");
el2.click();
MobileElement el3 = (MobileElement) driver.findElementByXPath("/Window/Window[2]/Group/Group[5]/Button[7]");
el3.click();
MobileElement el4 = (MobileElement) driver.findElementByXPath("/Window/Window[2]/Group/Group[4]/Button[5]");
el4.click();

まとめ&感想

このようにロケータ情報を記録してコード化することができました。
xPathオンリーなのが惜しいところです。
(せっかくAutomation IDが取れているのですから、そちらで欲しかった︕)
また、Appium Desktopからの制御にタイムラグがかなりあり、ちょっとストレスを感じました。
使いどころが限られるものの、大量のロケータをコード化する必要がある場合ならば、タイムラグの件さえ気にしなければ、活用できる可能性は残しつつも、最新のAppium Desktopでは動作しないことを考える(※2)と、このセッション機能が刷新されることに期待をするのはちょっと難しそうです。
次回はWindowsデスクトップアプリケーションにおける、xPathとAutomation ID(Accessibilities ID)の動作時間の相違について調べてみたいと思います。
※1 https://github.com/microsoft/WinAppDriver/releases/tag/UIR-v1.1
※2 https://github.com/microsoft/WinAppDriver/issues/1103

Appendix 他のアプリケーションでの動作確認

他の対応アプリケーションについてもザッと動作確認してみました。

画像8

※1 セッションウインドウのサイズはNormalの場合のみ動作可能です。拡大表示するとエミュレータの縦横比がずれてしまうようです。

Appendix 2

エクスポート時に「定形のコードを表示」オプションを有効化すると

画像9

親切なことにJavaモジュールをそっくり自動生成してくれます。(JUnit5で書いてほしい!)
ローコード開発みたいですね!(ちがう)

Appendix 3

今回はご紹介した方法はWinAppDriverをバージョン1.1.1がMSIインストーラ経由でインストールされていないと、Appium Desktopから認識されないためエラーとなります。これを回避する(または別バージョンのWinAppDriverを使用する)方法としては以下があります。いずれもAppium本体に手を入れることになりますので自己責任でお願いします。

Appiumのnode-modules配下の以下を修正

> Appium/resources/app/node_modules/appium/node_modules/appium-windows-driver/build/lib/installer.js

1) バージョンチェックを無効化

async function verifyWAD() {
   // anyway return true
   return true;

2)インストールパスを指定

//exports.WAD_INSTALL_PATH = WAD_INSTALL_PATH = _path.default.resolve(WAD_INSTALL_PATH, 'Windows Application Driver', 'WinAppDriver.exe');
exports.WAD_INSTALL_PATH = '{WinAppDriver.exeの絶対パス}';

――――――――――――――――――――――――――――――――――

執筆者プロフィール:森川知雄
中堅SIerでテスト管理と業務ツール、テスト自動化ツール開発を12年経験。
SHIFTでは、GUIテストの自動化ツールRacine(ラシーヌ)の開発を担当。
GUIテストに限らず、なんでも自動化することを好むが、
ルンバが掃除しているところを眺めるのは好まないタイプ。
さまざま案件で自動化、効率化による顧客への価値創出を日々模索している。

お問合せはお気軽に
https://service.shiftinc.jp/contact/

SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/

SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/

SHIFTの導入事例
https://service.shiftinc.jp/case/

お役立ち資料はこちら
https://service.shiftinc.jp/resources/

SHIFTの採用情報はこちら 
https://recruit.shiftinc.jp/career/