53
62

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Windows Application Driver を使った Windows ネイティブアプリケーションの UI テスト自動化

Last updated at Posted at 2018-07-18

2020/3/8 追記

  • 長らく放置していたため、リンク切れしていた箇所を修正しました。
  • サポート期間終了に伴い、Windows 7、8 の記載を削除しました。
  • UI エレメントの調査用のツールが増えていたので、記載を拡充しました。
  • General Development & Best Practicesについて最後に追記しました。
  • 現在は Windows 用の Appium から Windows Application Driver を呼び出すことができるため、改題しました。
    • 本記事は Windows App Driver 単体での利用について記載しています。

Windows Application Driver について

Android / iOS アプリの自動テストで有名な Appium ですが、2017年11月 にはこれまで長らくベータ提供だった Windows Application Driver が Microsoft より正式にリリースされました。
 Windows Blog:Windows Application Driver を正式にリリース

これまでも UWSC などを使って Windows ネイティブアプリを自動で操作することはできましたが、今回のリリースによって Selenium(Web アプリ)、Appium(スマホアプリ)で得た知見をそのまま Windows ネイティブアプリの UI テストにも生かすことができます。
これまで Selenium や Appium を触ったことがない人でも Java や Python など自分の慣れた言語でテストケースが書けるという大きなメリットがありますし、JUNIT などの既存のフレームワークも流用できます。
※なお、対応言語は Selenium / Appium に準じています。対応言語はこちらを参照してください。

以下、GitHub に公開されている WinAppDriverREADME.md を元にご紹介していきます。
※2018年7月時点での内容です。リポジトリが更新されていくにつれ内容が乖離する可能性がありますので、正確なところは WinAppDriver のリポジトリを参照してください。

よくある質問

FAQ をご確認ください。

システム要件

  • Windows 10 PC
  • Appium のテストランナー
    • これは Microsoft Visual Studio に限らず、使い慣れたものを使うのが良いでしょう。私は Python で実装しているので、VScode と Python 向けのプラグインを使っています。

なお、Appium のドキュメントの方には書いてあるのですが、管理者権限で実行できることが要件になります。
The Windows Driver: requirements-and-support
また、このドキュメントの Setup に記載されている通り、始めに Windows の開発者モードを ON にする必要があります。

Windows Application Driver のインストールと起動

まず、GitHub から Windows Application Driver をダウンロードします。
https://github.com/Microsoft/WinAppDriver/releases
2018年7月現在の最新は v1.1 Preview Release、最新の Stable は v1.0 Release です。お好きな方の .msi ファイルをダウンロード、インストールしてください。

インストール後、コマンドプロンプトから WinAppDriver.exe を実行してください。
デフォルトパスにインストールした場合は以下のコマンドになります。

"C:\Program Files (x86)\Windows Application Driver\WinAppDriver.exe"
Windows Application Driver listening for requests at: http://127.0.0.1:4723/ #コマンド実行後にこれが表示されれば OK
Press ENTER to exit.

デフォルトだと Localhost のポート 4723 で起動しますが、IP、ポート番号のいずれも起動時の引数で指定することが可能です。

WinAppDriver.exe 4727
WinAppDriver.exe 10.0.0.10 4725
WinAppDriver.exe 10.0.0.10 4723/wd/hub

※ デフォルトとは異なる IP/ポートを使用する場合は、WinAppDriver.exe を管理者モードで実行してください。

自動テストの作成

テストのサンプル

Alarms & Clock, Calculator, and Notepad などの Windows 10 ビルトインアプリを対象とした各言語でのサンプルコードはこちらです。

アプリの起動や各エレメントの見つけ方、クリック、キーストローク、テキストの読み取りなどの色んなバリエーションがあるそうです(あんまり見ていない)。

テストケースの実装

Authoring Your Own Test Script では C# でのテストコードの書き方が説明されています。

私は Python を使っていますが、API などの名称が大文字、小文字で変わったりする程度で、基本的な実装は変わりません。
例えば『Testing a Universal Windows Platform Application』のソースコードを Python で書くと

uwpa_test.py
from appium import webdriver

# Launch the Alarms & Clock app
desired_caps = {}
desired_caps["app"] = "Microsoft.WindowsAlarms_8wekyb3d8bbwe!App"
alarm_clock_session = webdriver.Remote(
    command_executor='http://127.0.0.1:4723',
    desired_capabilities= desired_caps)


# Use the session to control the app
alarm_clock_session.find_element_by_accessibility_id("AddAlarmButton").click();
alarm_clock_session.find_element_by_accessibility_id("AlarmNameTextBox").clear();

ですし、『Testing a Classic Windows Application』を Python で書くと

cwa_test.py
from appium import webdriver

# Launch Notepad
desired_caps = {}
desired_caps["app"] = r"C:\Windows\System32\notepad.exe"
desired_caps["appArguments"] = "MyTestFile.txt"
desired_caps["appWorkingDir"] = r"C:\MyTestFolder" + "\\"
notepad_session = webdriver.Remote(
    command_executor='http://127.0.0.1:4723',
    desired_capabilities= desired_caps)

# Use the session to control the app
notepad_session.find_element_by_class_name("Edit").send_keys("This is some text");

こうです。
実行に必要なライブラリは pip install robotframework-appiumlibrary でインストールできます。

UWPA はアプリケーションの ID を指定するだけで実行できますが、従来の Windows アプリケーションの場合は実行時コマンドのフルパスで指定する必要があります。いずれの場合でも appArguments で起動時の引数を指定することが可能ですが、appWorkingDir の指定は従来の Windows アプリケーションのみ有効なようです。

DesiredCapabilities という JSON オブジェクトが急に出てきましたが、ここら辺を正確に理解するには Appium のドキュメントを参照してください。

Supported Capabilities

Capabilities Descriptions Example
app Application identifier or executable full path Microsoft.MicrosoftEdge_8wekyb3d8bbwe!MicrosoftEdge
appArguments Application launch arguments https://github.com/Microsoft/WinAppDriver
appTopLevelWindow Existing application top level window to attach to 0xB822E2
appWorkingDir Application working directory (Classic apps only) C:\Temp
platformName Target platform name Windows
platformVersion Target platform version 1

DesiredCapabilities で設定できる Capabilities の一覧が紹介されています。
先の例で desired_caps["app"] = "Microsoft.WindowsAlarms_8wekyb3d8bbwe!App" と指定していたのが、この一覧でいう app という Capabilities です。

UI エレメントを指定するための Supported Locators

Client API Locator Strategy Matched Attribute in inspect.exe Example
FindElementByAccessibilityId accessibility id AutomationId AppNameTitle
FindElementByClassName class name ClassName TextBlock
FindElementById id RuntimeId (decimal) 42.333896.3.1
FindElementByName name Name Calculator
FindElementByTagName tag name LocalizedControlType (upper camel case) Text
FindElementByXPath xpath Any //Button[0]

Appium では操作する UI エレメントを指定する際に、その ID や名前を事前に調べておき、それらを指定する必要があります。
先の例で alarm_clock_session.find_element_by_accessibility_id("AddAlarmButton") と指定している箇所では、Alarms & Clock アプリの UI のうち、新しいアラームを追加するボタンを AddAlarmButton という accessibility id で指定しています。

UI エレメントを調べる

inspect.exe

上記の UI エレメントはテストケースを実装する際に調べておく必要がありますが、最新の Microsoft Visual Studio に含まれる Windows SDK の中にはこれを調べられる inspect.exe というツールがあります。
使い方については、MSDN のドキュメントを参照してください。

Windows SDK をインストールされている場合は C:\Program Files (x86)\Windows Kits\XX\bin\x86 に配置されています。
※XX は番号で、8.0 以降であれば inspect.exe が同梱されているようです。

Windows SDK をインストールしていない場合は以下のリンクなどからダウンロードしてインストールしてください。
https://developer.microsoft.com/en-us/windows/downloads/sdk-archive

inspect.exe を実行すると現在実行中のアプリが全てアプリの左側にツリー表示されるので、特にドキュメントを調べなくても使い方は直感的に分かると思います。

UI Recorder

UI Recorder という便利なツールがあるようです。UI の動きを記録して C# のコードまで出してくれるので、C# 使いはこれを採用するのが良さそうです。

ただし、同様の機能を備える下記の appium-desktop では、自動生成されるコードは本番用のテストコードではなく、あくまで対応している Appium ライブラリをコードで教えてくれる学習ツールである、と補足がありました。
実際に見てはいませんが、自動生成されたコードは使用する前に開発者の方で精査、必要に応じて修正するのが良いと思います。

Appium Desktop

Appium Desktop は Mac、Windows、Linux 上で動作するデスクトップアプリケーションです。
これに Recorder の機能があるため、これを使って UI エレメントを調べることができます。

しかし、Windows Application Driver をインストールしている環境で UI エレメントを調べるためだけに Appium Desktop をわざわざインストールするのはオーバースペックであり、過剰です。
※ クロスプラットフォームで使っている場合などは、採用しても良いと思います。


クラシックな Windows アプリでは一般的な操作にはショートカットキーが割り当てられているので、UI エレメントを指定せずに send_keys でショートカットキーを実行することで済ませることもできます。

コンパクトに、簡単に実装できるので簡単な検証用のコードとしては良いかもしれませんが、この方法ではコードの可読性も含めた保守性に難があるかもしれません。
また、テスト実行中に別プロセスがウィンドウを立ち上げた時などに影響を受けそうです。

おまけ: スクリーンショットのサンプル

一般的な UI テストの自動化であれば、アプリケーションに対して特定の操作を行なった後にスクショを撮るのが基本的な流れになると思います。
先ほどの Alarms & Clock アプリを例に、自動実行結果のスクリーンショットを取得するコードをおまけに記載しておきます。

screenshot.py
from appium import webdriver

# Launch the Alarms & Clock app
desired_caps = {}
desired_caps["app"] = "Microsoft.WindowsAlarms_8wekyb3d8bbwe!App"
alarm_clock_session = webdriver.Remote(
    command_executor='http://127.0.0.1:4723',
    desired_capabilities= desired_caps)

# Use the session to control the app
alarm_clock_session.find_element_by_accessibility_id("AddAlarmButton").click();
alarm_clock_session.find_element_by_accessibility_id("AlarmNameTextBox").clear();

# Take and save screenshot
screenshot = alarm_clock_session.get_screenshot_as_png()
with open(r"C:\MyTestFolder\add_alarm.png", "wb") as fout:
    fout.write(screenshot)

# Quit app
alarm_clock_session.quit()

上記のコードを実行すると、Alarms & Clock アプリが自動実行されたウィンドウのスクリーンショットが C:\MyTestFolder\add_alarm.png として保存されます。


さまざまなテクニックは General Development & Best Practices にもまとめられているので、ご参照ください。

53
62
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
53
62

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?