Appiumこんにちは。SWETの外山(@sumio_tym)です。書籍「Androidテスト全書」を執筆したりしていました1。今回はAppiumを使ったAndroidのUIテスト自動化業務で得られたノウハウを紹介します。Appiumを使ったUIテスト自動化経験があっても、使っているプログラミング言語は組織やプロジェクトによって様々だと思います。クライアントライブラリにWebdriverIOを採用するときのノウハウを次の3点に分けて説明します。セットアップするときのポイントテストコードを書くときのポイントテスト失敗時に解析しやすくする工夫Appium経験者に向けたエントリーであるため、Appiumの詳しい解説はしていません。Appiumについて詳しく知りたい方は公式ドキュメントを参照してください。ノウハウの一部はAndroidでしか通用しないものもありますのでご注意ください。WebdriverIOとはAppium向けのクライアントライブラリのうち、JavaScriptに対応しているものは次の2つです。どちらもJavaScript(Node.js)によるWebDriver実装です。WD.jsWebdriverIO今回取り上げるWebdriverIOで特徴的なものは次の2点です。同梱されているCLIベースのテストランナーwdioWebdriverIOサービスプラグインwdio-appium-servicewdioを使うと、async/awaitを使わずともテストコードを同期的に書くことができます。JavaScriptに付きものの非同期処理から解放されてテストコードを書けるのは、思いの外便利です。wdio-appium-serviceはWebdriverIOとAppiumを協調動作させるためのプラグインです。このプラグインを使えばテスト実行・終了と合わせて、自動的にAppiumを起動・終了してくれます。以降で説明するようにセットアップすれば、両者の機能をフル活用してテストを書き始めることができます。今回は次のバージョンで動作を確認しました。0.2.3セットアップするときのポイントインストールと設定ファイルの雛形作成Node.jsは既にインストールされているものとします。以下のようにwebdriverioパッケージをインストールします。webdriverio次に、以下のコマンドを実行します。このコマンドは対話形式でWebdriverIOの設定ファイルを作成するものです。configいくつか質問されますが、以下の質問以外は全てデフォルトのままEnterを押して先に進めてください。テスト結果レポートをどのように表示するか選択します。こだわりがなければspecとjunitを選択しておくのが無難です。appiumを選択します。ここでappiumを選択すると、テスト実行の度にAppiumが自動的に起動するようになります。原因解析に有用ですのでverboseにするのがお勧めです。全ての質問に回答するとWebdriverIOの設定ファイルwdio.conf.jsの雛形が生成されます。あわせて、関連パッケージが自動的にインストールされます。最後にAppium本体とアサーションライブラリ(ここではchai)をインストールします。生成された設定ファイルwdio.conf.jsは、そのままではAppiumを使ったテストを書くことができません。少なくとも以下の修正が必要です。そのときにAppiumも同じ待ち受けポートで複数個起動してしまい、うまく動作しません。その事象を回避するため、maxInstancesを1にしてください。Capabilitiesが設定されています。Capabilitiesに置き換えてください。以下のようになります。配列の要素は1つだけにしてください。複数の要素を持たせると、書いた要素の数だけAppiumが同時に起動してしまいます。こちらも同じ理由で削除しなければなりません。WebdriverIOの接続先ポート番号のデフォルト値は異なります。そのため、以下のとおり接続先を明示的に指定してください。testでテストを実行できるようにする最後に、package.jsonを以下のように変更します。testコマンドを使ってテストを実行できるようになりました。テストコードを書くときのポイント次に、テストコードを書くときに、Appiumだからこそはまるポイントを説明します。次の点を押さえておくと、これから説明する内容が理解しやすくなると思います。UIコンポーネントを探せるのがWebdriverIOの特徴のひとつになっています。この書き方はブラウザを操作するときであれば威力を発揮するものの、モバイルアプリではそうはいきません。「テキスト」の判定は、ブラウザを前提とした公式ドキュメントの説明に惑わされてはいけません。/>になるため、WebdriverIOの簡略記法は使えないのです。Androidの場合は、次のようなユーティリティメソッドを用意しておくと良いでしょう。「OKと表示されたUIコンポーネントをクリックする」という操作は次のように書けます。ドキュメントには、あるコンポーネントが画面内に入るまでスクロールできると書かれています。このメソッドはAppiumでは動作しませんので、自身で実装が必要です。下方向にスクロールする実装は次のようになります。画面中央をタップし、少し200pxだけy方向に動かす。}このサンプルコードでは、最初に端末の画面サイズを取得しています。その後、目的のUIコンポーネントが画面内に見つかるかタイムアウト(ここでは180秒)するまで、以下の処理を繰り返しています。pressで画面中央をタップしますwaitで500msec待ちます。1.8より必要になりましたmoveToで、画面中央から200pxだけ下方向に指を動かしますreleaseで指をリリースしますテスト失敗時に解析しやすくする工夫テストに失敗したときには、次の情報があると解析が捗ります。Appiumのログテストに失敗したときのスクリーンショットテストを実行した端末のログこのうちAppiumのログは、ログレベルをverboseにしておけば標準出力に表示されます。残りの2つについてAndroidの場合の設定を紹介します。スクリーンショットを保存するWebdriverIOはデフォルトで、コマンド(browserが提供している各メソッド)実行に失敗したタイミングでスクリーンショットを保存してくれます2。ところが、画面に表示されている文字列が想定と異なる場合などではスクリーンショットが保存されません。そのようなケースではassertには失敗しているものの、コマンドの実行は成功しているからです。この問題を解決するため、テスト失敗時(assertに失敗したとき)にもスクリーンショットを保存するようにします。テストが終了する度にwdio.conf.jsのafterTest関数(デフォルトではコメントアウトされています)がコールバックされるため、その中にスクリーンショットを保存する処理を書いていきます。このサンプルコードでは./screenshots/ディレクトリにscreenshot-2018-10-02T21:58:29+0900.pngのようなファイル名でスクリーンショットを保存しています。installコマンドでdateformatをインストールしておいてください。スクリーンショットを取得しているのはbrowser.saveScreenshot()です。明示的にawaitキーワードを付けて処理の終了を待たなければならない点に注意してください。logcatを保存するWebdriverIOではbrowser.log()の引数に‘logcat’を指定することで、logcatを取得できます。スクリーンショットを保存したときと同じく、wdio.conf.jsのafterTest関数に処理を追加していきましょう。前述のスクリーンショット保存コードに続けて、次のコードを追加してください。});browser.logcat()はlogcatの各行(timestampとmessageで構成)を要素とした配列を返します。./logsディレクトリにlogcat-2018-10-02T21:58:29+0900.logのようなファイル名で保存しています。前述の2つの処理を書いたafterTest関数の全体像は次の通りです。コピーして試してみる場合は、./logsディレクトリと./screenshotsディレクトリを事前に作成しておいてください。まとめWebdriverIOでAppiumを使ったテストを書くときのノウハウを紹介しました。本エントリで紹介した内容を押さえておけば、基本的なテストは書き始められると思います。参考にしてみてください。ありがたいことに、業務時間の一部を執筆活動に充てることをリーダーの@okitanさんに快諾していただきました。保存先はwdio.conf.jsのscreenshotPathで指定したディレクトリ(デフォルト値は'./errorShots/')です。11でのテスト周りの新機能を紹介します!SWETグループ、iOS自動テスト領域チームの細沼(tobi462)です...2018-11-05本日(11/5)販売開始:書籍「Androidテスト全書」のUIテスト部分を執筆しましたこんにちは。SWETの外山(@sumio_tym)です。本日、書籍「Andr...2018-05-10SWETの新メンバーから見て驚いたこと、そこから生まれたDIライブラリ不使用宣言はじめまして!4/1よりSWETに加わった@Kuniwakです。2018参加レポートはじめまして。SWETの外山(@sumio_tym)です。2018年1月よりS...2018-01-22Golangでtestingことはじめ(2)〜テストにおける共通処理〜こんにちは。(1)リンクプライバシーポリシースターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。