iOS/AndroidのUIテストを自動化するAppiumのテストスクリプトの書き方とインスペクターの使い方:スマホ向け無料システムテスト自動化ツール(9)(1/3 ページ)
本連載では、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()」メソッドの中身を一つ一つ見ていきます。
DesiredCapabilitiesの準備
「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のもう一つの指定方法」
Desired Capabilitiesで指定できる条件の中には、Appiumサーバー起動時に設定できるものもあります。
例えば、前回の「Appiumサーバーの起動」では「Android Settings」→「Application」→「App Path」にテスト対象のapkファイルを指定しましたが、それはDesired Capabilitiesの「"app"」を指定することに相当します。
また、Androidボタンの下にあるラジオボタンを選択状態にしたことは、「platformName」に「"Android"」を指定したことを意味します。
Appium GUI版で設定できる項目の詳細はAppium GUIのParameter Guideを参照してください。
AndroidDriverインスタンスの生成と暗黙の待ち時間の設定
上記コード例の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.
関連記事
- テスト自動化の歴史と今後、良い/悪い事例〜システムテスト自動化カンファレンス2013レポート
テスト自動化を開発の“武器”にするための3つのポイントや、“自動化”の良い事例、悪い事例など、テストの現場を「進化させる」知見が多数紹介されたカンファンレンスの模様をレポートする。 - ビジネス目標を見据えたテスト設計が肝!「DevOps時代のテスト自動化カンファレンス 冬の陣」開催
DevOpsの実践で肝となるソフトウェアテストの自動化。しかし@ITの読者調査でも50%以上が「テスト環境に課題あり」と回答した。これにどう対応すれは良いのだろうか? カンファレンス登壇者の言葉にヒントを探る。 - Kiwi+CocoaPodsで始めるiOSアプリの振る舞いテスト入門
現代の開発現場において欠かせないCI/継続的デリバリを、iOSアプリ開発に適用するためのツールやノウハウを解説する連載。今回は、iOSアプリの機能の振る舞いをテストするテスティングフレームワークの特長とインストールの仕方、主な使い方を解説します。 - Android SDKでビジネスロジックのテストを自動化するには
- 第2回Androidテスト祭りレポート:Android開発の上層テストで失敗しないためのポイントとは
セキュリティ設計や受け入れテストガイドライン、CIツールJenkins+コードレビューGeritt、テスト効率化ノウハウ、リモートテストサービスなど