本連載では、AndroidおよびiOSアプリ開発における、システムテストを自動化するツールを紹介していきます。今回は、オープンソースのモバイルテスト自動化ツール「Appium」のテストスクリプトの書き方や、インスペクターの使い方、Appiumサーバーのコマンドラインからテストを実行する方法などについて。
本連載では、スマートフォン(Android/iOS)アプリ開発における、システムテストを自動化するツールを紹介しています。
前回の「SeleniumのUIテスト自動化をiOS/AndroidにもたらすAppiumの基礎知識とインストール方法、基本的な使い方」から、オープンソースのモバイルテスト自動化ツール「Appium」の特徴や基本的な使い方を説明しています。
今回はJava言語でのテストスクリプトの書き方や、インスペクターの使い方、Appiumサーバーのコマンドラインからテストを実行する方法などを見ていきます。
Java言語向けのAppiumクライアントライブラリは、Seleniumクライアントライブラリを拡張したものになっています。そのため、AppiumクライアントライブラリのAPIリファレンスと、SeleniumクライアントライブラリのAPIリファレンスの両方を参照しながらテストスクリプトを書く必要があります。
以降では、サンプルのテストスクリプトを例に、Appium modeで、AndroidアプリのWebView以外の部分(「ネイティブ」と呼ばれる部分)をテストする場合について説明します(WebViewをテストする場合やSelendroid modeについても最後に軽く触れます)。
また、Appium独自のAPIを主に説明し、SeleniumクライアントライブラリのAPIについては必要に応じて補足します。SeleniumクライアントライブラリのAPIのより詳しい使い方については、書籍『実践Selenium WebDriver』(オライリージャパン刊)を参照してください。
Appiumのテストを開始するには、最初にAndroidDriverインスタンスを生成し、自動化セッションを開始する必要があります。テスト終了後には、開始した自動化セッションを終了します。
Appiumは、自動化セッション開始・終了のタイミングで、テスト対象アプリを起動・終了します。
また、テスト対象アプリの起動前にアプリ専用データの削除(連載第3回記事のコラム「端末内のアプリ専用領域に保存されたデータを消したい場合」と同じ方法を使っています)も行い、毎回同じ状態からテストが開始できるようになっています。
サンプルのテストスクリプトの「com.nowsprinting.hellotesting.appiumtest.appium.AddCustomerTest」クラスのコードは以下の通りです。「setUp()」メソッドで自動化セッションを開始し、「新規顧客が追加できること()」メソッド(テストメソッド)でテストを実施し、「tearDown()」メソッドで自動化セッションを終了しています。
public class AddCustomerTest { private AndroidDriver mDriver; @Before public void setUp() throws Exception { DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.setCapability(CapabilityType.BROWSER_NAME, ""); capabilities.setCapability(MobileCapabilityType.APP_PACKAGE, "com.nowsprinting.hellotesting.appium"); capabilities.setCapability(MobileCapabilityType.APP_ACTIVITY, "com.nowsprinting.hellotesting.app.CustomerListActivity"); capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator"); capabilities.setCapability("unicodeKeyboard", true); capabilities.setCapability("resetKeyboard", true); mDriver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities); mDriver.manage().timeouts().implicitlyWait(80, TimeUnit.SECONDS); } @After public void tearDown() throws Exception { mDriver.quit(); } @Test public void 新規顧客が追加できること() throws Exception { // (ここでテストを実行する) } }
JUnit 4ではテストメソッドの実行順序が定まっていないため、直前のテスト実行結果(アプリ操作結果)に依存したテストを書いてはいけません。このサンプルコードのように、「setUp()」メソッドで自動化セッションを開始し、テスト対象アプリをクリーンな状態で起動し直すことで、直前のテスト実行結果に依存しないテストにすることができます。
以降では、「setUp()」メソッドと「tearDown()」メソッドの中身を一つ一つ見ていきます。
「setUp()」メソッドの先頭(コード例7〜13行目)では「DesiredCapabilities」インスタンスの準備をしています。「DesiredCapabilities」は「テストが実行されるAppiumサーバーの性質・機能」を指定するもので、このコード例のように複数のキー・バリューの組で指定します。
「DesiredCapabilities.setCapability()」で指定できるキーの一覧はAppium server capabilitiesにまとめられていますが、主なものは以下の通りです。
キー名 | 利用可能?(○:利用可、−:利用不可) | 意味 | |
---|---|---|---|
Android | iOS | ||
"browserName" (CapabilityType.BROWSER_NAME) |
○ | ○ | テスト対象のブラウザー名を指定する。今回はブラウザーではなくアプリをテストするため、空文字列("")を指定している |
"platformName" (MobileCapabilityType.PLATFORM_NAME) |
○ | ○ | プラットフォームを"iOSか"Android"で指定する。Javaのクライアントライブラリでは、IOSDriver、AndroidDriverのどちらを生成したかによって自動的に値が定まるため、コード上で明示的に指定する必要はない。 |
"platformVersion" (MobileCapabilityType.PLATFORM_VERSION) |
− | ○ | iOSエミュレーターのOSバージョンを指定する |
"deviceName" (MobileCapabilityType.DEVICE_NAME) |
○ | ○ | テストを実行する端末の名前を指定する。Androidでは、どんな値を指定しても無視される。テスト対象アプリおよびテストは、adb devicesコマンドで先頭に表示される端末もしくはエミュレーター上で実行される。iOSでは、「instruments -s devices」コマンドで得られる名称を指定する |
"udid" | - | ○ | iOS端末(実機)を使用するとき、そのUDIDを指定する |
"app" (MobileCapabilityType.APP) |
○ | ○ | テスト対象アプリのapkファイル・ipaファイルの所在をフルパスで指定する。httpのURLで指定することもできる |
"automationName" (MobileCapabilityType.AUTOMATION_NAME) |
○ | − | 自動化のモード(Appium mode、またはSelendroid mode)を指定する。Appium modeにしたい場合には"Appium"を、Selendroid modeにしたい場合には"Selendroid"を、それぞれ指定する。省略した場合はAppium modeとみなされる |
"appPackage" (MobileCapabilityType.APP_PACKAGE) |
○ | − | テスト対象アプリのパッケージ名(AndroidManifest.xmlのpackage、もしくは、build.gradleのapplicationId)を指定する |
"appActivity" (MobileCapabilityType.APP_ACTIVITY) |
○ | − | テスト対象アプリのActivityのうち、テスト開始時に開始してほしいものを指定する |
なお、Appiumのテキスト入力APIはuiautomatorと同じ制限事項を抱えています。具体的には、テストを実行する端末のIMEが英語入力モードでないと、想定とは異なる文字列が設定されてしまうことがあり、非ASCII文字の入力ができません。
前述のコード例には、表に挙げた項目以外に「"unicodeKeyboard"」「"resetKeyboard"」を指定していますが、これらを指定することで、テキスト入力APIの制限事項を回避できます。
より詳しくはMulti-lingual Supportを参照してください。連載第3回の記事で紹介したものと同じ仕組みが採用されています。
Desired Capabilitiesで指定できる条件の中には、Appiumサーバー起動時に設定できるものもあります。
例えば、前回の「Appiumサーバーの起動」では「Android Settings」→「Application」→「App Path」にテスト対象のapkファイルを指定しましたが、それはDesired Capabilitiesの「"app"」を指定することに相当します。
また、Androidボタンの下にあるラジオボタンを選択状態にしたことは、「platformName」に「"Android"」を指定したことを意味します。
Appium GUI版で設定できる項目の詳細はAppium GUIのParameter Guideを参照してください。
上記コード例の14行目では、AppiumサーバーのURLと、準備した「DesiredCapabilities」インスタンスを、コンストラクターの引数に指定して、「AndroidDriver」インスタンスを生成しています(この時点で自動化セッションが始まります)。AppiumサーバーのURLには、同一マシン上でAppiumサーバーを起動し、特に設定を変更していなければ、「"http://127.0.0.1:4723/wd/hub"」を指定してください。
「setUp()」メソッドの最後の行(15行目)は、画面上のUIコンポーネントを探し始めてから、実際に表示されるまでにリトライし続ける時間(暗黙の待ち時間)を80秒に設定しています。この行はなくても構いませんが、Androidエミュレーターでテストを実行するときなど、テスト対象アプリの応答が遅い場合には、長めの時間を指定しておくとテストが失敗しにくくなります。
「tearDown()」メソッド(18〜21行目)では、自動化セッションを終了しています。「AndroidDriver」インスタンスに対して「quit()」メソッドを呼び出すと、自動化セッションが終了します。
Copyright © ITmedia, Inc. All Rights Reserved.