DroidDriverのJavaDocをもすこし読んでみた。 io.appium.droiddriverのJavaDocsより 以下、いくつかピックアップして読んでみた。 BaseDroidDriver DroidDriverを使ってテストを記述するとき、通常は BaseDroidDriverTest を継承して使う。 BaseDroidDriverTest は、 D2ActivityInstrumentationTestCase2 を継承している。 D2ActivityInstrumentationTestCase2 は ActivityInstrumentationTestCase2 を継承している。 D2ActivityInstrumentationTestCase2 は ActivityInstrumentationTestCase2 で既知の不具合であるISCよりも小さなバージョンのOSで再現するNullPointerExceptionの修正を含んでいるとのこと。 D2ActivityInstrumentationTestCase2 にある scrubClass の引用 Fixes a bug in ActivityTestCase.scrubClass(java.lang.Class) that causes NullPointerException if your leaf-level test class declares static fields. This is a known bug that has been fixed in ICS Android release. But it still…More
Tag Archives: automation
忘れないようにIntentのUnitTestを書いてみた
昨日の記事をちょっと手を動かしておこうと思って、IntentのUnitTestを書いてみた。ついでに、@RunWith(AndroidJUnit4.class)を有効にして。 AndroidJUnit4.classを使うにあたってエラーが出て修正したポイントは2つ。あとおまけで1つ。 injectInstrumentationによるInstrumentationへのinject これしないと、super.setUp()で落ちる InstrumentationRegistry.getInstrumentation().runOnMainSync()によるintentからのActivityの起動 これしないと、startActivityがヌルポで落ちる ContextThemeWrapperを使うことで、R.style.AppThemeをテスト時にレイアウトとして使う レイアウトを独自でカスタマイズしている場合、AppThemeが無いみたいなエラーが出てきました どうやら、ContextThemeWrapperで仮のレイアウトを使うことで回避できるもよう 今回はあくまでもintentの確認なので、まー、よしですかね UIスレッドの話しなんかも、対応を終えたあとはなるほどなーという感じ。 ちょっと記述量を減らしたく、ButterKnifeを使ってみました。おまけ程度。 内容は、 com.example.activityのアクティビティを起動する 表示されるボタンをタップして、別アクティビティ(com.example.activity.Next)を起動する という内容に対して、期待したintentが飛ぶことを確認する、というものです。 ActivityUnitTestCaseなので、その実際が描画されたりはしません。これ、Integrationレベルで確認すると、Espressoを使って描画ベースの存在確認を行いますね。 ふぅ。Intent、いろいろちゃんとしておかないと魔の巣窟になって危なそうですね。サービスが肥大化してくると特に。怖い怖い。 最近、StethoをVolleyに適用しようとしています。単純に適用しようとすると、VolleyのHttpStackを活用してOkHttpStackのようなクラスを作成し、QueueRequestにHttpStackを与えます。 なのですが、今取り組んでいるところはそのような形でさくっとできるような所ではなく、少し手惑い気味。More
UIAutomator2.0がリリースされていた
3月13日、以下の通りAndroidのUIAutomator 2.0がリリースされていたのですね。 https://plus.google.com/+AndroidDevelopers/posts/WCWANrPkRxg uiautomatorは、AndroidのAccessibility機能やその拡張を介して、インストールされた様々なapkを操作するフレームワークでした。そのため、例えばリリース用apkに対してシナリオテストを自動化するときなんかに使います。例えば、AppiumはAndroidに対してはこのuiautomator1.0を利用してテストを実施することをしています。 uiautomatorあらため、UI Automator 2.0の新しいところは、Instruments経由でUiElementsなどを使えるようになったことらしいです。これにより、./gradlew connectedCheck なんかのコマンドでUI Automatorによるテストを実施できるようになったとか。 まだASOPには公開されていませんが、Appiumのメンバらも公開されたら良さそうなら統合とかするでしょうし、DroidDriverとももしかすると競合するところがあるのかもしれません。 2014年12月のEspresso2.0のリリースとそれに伴うJUnit4の提供、UI Automatorの更新と、比較的テストツールの充実が図られていて良い感じですね。 Testing Support Libraryが提供する大きな機能 AndroidJUnitRunner: JUnit 4-compatible test runner for Android Espresso: UI testing framework; suitable for functional UI testing within an app UI Automator: UI testing framework; suitable for cross-app functional UI testing across system and installed apps AndroidJUnitRunner Require Android2.2(API Level8)…More
Appiumを使った文字入力とcontext switch
Appiumに関して、以下の2点に関してメモがてら。 文字入力 WebView(Hybrid view) 以下、Appium1.3.4の時の話です。 文字入力 iOSでは、Appium(というか、Selenium)が提供するキー入力にsendKeysが存在します。また、UIAutomationでは、setValueが提供されています。 iOSでは、マルチバイト文字入力含め、setValueによる文字入力のほうが安定しています。ですが、全てのテキストフィールドにそれを使うことができるわけではありません。SecureTextFieldに関しては、sendKeysを使わなければ正常に文字入力ができませんでした。 そのため、安定したテストを書くためには、TextFieldにはsetValueを、SecureTextFieldのみはsendKeysを使いましょう。 Rubyのライブラリの話をすると、appium_libのこの行を参考にすると、以下の通り type で定義されているメソッドに内包されています。 また、同様にソースを見ると、このメソッドはAndroidではsend_keysとして扱われています。 そのため、以下のようなルールを設けて実施すると良いでしょう。 SecureTextFieldを対象にしている場合はsend_key ↑以外の場合はsetValue こんな感じで内包することになるでしょうか。 WebView Hybridアプリの場合、contextを変更することでネイティブ、WebViewのそれぞれを操作対象として変更することができます。 なのですが、iOSアプリの一部WebViewで操作する必要のある画面をiOS Simulatorで実行していた時の話です。contextでWebViewに設定しても期待通りに動作しませんでした。むしろ、正常に要素すら取得できていなかったです。逆に、Nativeで実施すると正しく動作した。 AndroidやiOS real deviceの話までは詳しく追ってはないのですが、context switchはいらないのか…??More
システムテスト自動化 標準ガイドを読んだ
この土日は積読の消化をしようと、システムテスト自動化 標準ガイドともう1冊読みました。ここではシステムテスト自動化の本を残します。 このTweetの通り、内容は システムテスト に限りませんでした。個人的には システム は入れなくても良かったのでは・・・と思いました。 実際に自動化に取り組んでいたり、代表的なテストの書籍を読んでいるとそうだよな、という感じで納得できる内容が丁寧にまとまっている感じでしょうか。特に、キャプチャ&リプレイの話だったり、保守しやすい形、自動比較の話なんか。 今、第4章の自動比較、検証が個人的に今悩んでいます。特に、モバイルアプリではViewに対する評価を、単なる表示される要素の確認以上しようとすると画像比較以外できません。その画像比較は最終的には人の目に頼らざるおえないので、時折漏れが発生します。そのため、人目で見ることを前提に、気づきを得られるような施策を打つことはしますがそれ以上どこまでできるか考えます。 これ読んでて思ったのですが、なんだかんだで私はデータ駆動、キーワード駆動のテストまで実装していたのですね。More
ActionSheet()ではなくaccessibility_idでアクションシートの要素を操作する
UIAutomationで、actionSheetの取得は正常に実施できないので、accessibility_idによる要素取得にしたほうが良さそうだ。 alertは問題ないので、alert viewに関してはそこまで考えなくても良さそう。 例えば、以下のようにactionSheetを取得しようとすると、UIAElementNilが取得される。むむむ。。。 info: [debug] Got result from instruments: {“status”:17,”value”:”Cannot perform action on invalid element: UIAElementNil from target.frontMostApp().actionSheet().buttons()[\”キャンセル\”]”} info: [debug] Responding to client with error: {“status”:17,”value”:{“message”:”An error occurred while executing user supplied JavaScript.”,”origValue”:”Cannot perform action on invalid element: UIAElementNil from target.frontMostApp().actionSheet().buttons()[\”キャンセル\”]”},”sessionId”:”b412bcd4-d867-43df-9e3e-cafe2672ca05″}More
テストカメレオン
ふと、購読中の配信情報見てみると、テストカメレオンなるテストサービスを見つけました。 TestChameleon !! 変幻自裁なアーキテクチャを持ってるのかな?とか、多様なサービス持っているのかな?と思いざっと読んでみました。機能自体は、SauceLabsやBrowserStackみたいなものですが、そのテスト実行環境のアーキテクチャが貼られていたところが個人的に面白かったです。 以下、画像は以下URLから引張てきています。おもしろそうだと感じた方は一読してみると良いかもしれません。 http://www.ministryoftesting.com/2015/03/automated-testing-cloud-testchameleon/ Architecture Selenium Hub使っているのですね。最近だと、iOSが絡むところ以外がEC2上などにブラウザ環境を構築できるようになってきたので、こういうテストサービス自体の価格や自動化の障壁も下がってきましたね。嬉しいことです。 Dashboard Documents https://dashboard.testchameleon.com/media/tech-docs/_build/html/ APIs https://dashboard.testchameleon.com/media/tech-docs/_build/html/technical_doc.html 所管 提供されるテストの記述がJavaの例だったのですが、Groovyやらでかけるようなラッパー用意すれば使いやすそう。RubyやGroovy、Pythonのような感じの、少ない記述でテストかける方が私は嬉しいな。 SauceLabsやTesetDroidのように、モバイルアプリ/モバイルWebのテスト環境が整っているサービスはやはりまだ少ない模様。一方、Web Browserの環境を提供するものは増えてきて価格競争に突入しそうな雰囲気がひしひしと伝わってきますね。 競争。。。More
モバイルアプリにおけるE2Eテストの自動化に関して少しまとめる
少し前に、雑にモバイルアプリのリリースサイクル毎で行っているテストの流れという記事を書きました。 考え方が少し変わったりしているのですが、そこからE2Eテストという枠を抜き出して、さらにはテスト自動化という文脈で少し話を整理してみようと思います。 ここでは、効率的なコード、失敗時の解析の容易さなどに対する言及は致しません。また、サーバ側に対するテストの話にはちゃんとは触れません。 E2Eテストに含まれる目的 モバイルアプリにおけるE2Eテストという言葉には、恐らく以下の目的(と雑なテストタイプ)が含まれていることが多いと思います。 アプリのGUIから操作した (もしくは表示される要素に対して直接操作した)という文脈を持ったうえでの、 シナリオテスト 想定したStoryやFeatureを含んだシナリオを用意し、そのシナリオを達成できるかを検証したい 機能テスト(システム全体) サーバ側機能を含んだ、モバイルアプリのGUIから操作して意図した通りに機能が単体で振る舞うかを検証したい シナリオとして複数機能をまたがって何かする、という所までは見ない 統合テスト サーバからの応答をえた上で、モバイルアプリのGUI上で描画される要素を検証したい サーバはモック/スタブサーバでも特に限定しない。モバイルアプリ自体を構成する機能を統合させた上で正しく動作するかを見るもの。 GUIテスト 画面の表示、ボタンは位置などのレイアウトに対するGUIのレイアウト崩れ、描画される要素の過不足を検証したい 画面サイズ、解像度、フォントサイズ、アクセシビリティなどを考慮 なお、4に関しては端末のガイドラインに準拠しているかといった内容や、ユーザビリティに対する話は含まれません。 自動化する時に検証する方法 目的4以外のものに関しては、多くはGUIからの操作なので入力に対する出力を得て、その出力に対してアサーションをとることで検証を行うことでしょう。 4のGUIテストに関しては、モバイルアプリの場合は必ずスクリーンショットをとる必要が出てくるでしょう。描画される要素の有無であれば不要ですが、レイアウトが期待通りか、という所まで検証しようとすると、要素が描画された上で確認しなければ正しい/正しくないの判断ができないためです。例えば、画面サイズや解像度の多様性により表示がおかしくなるというのはAndroid/iOSともに多く有ります。 どこまで検証するか GUIから操作するという文脈を持つテストの場合、多くは実行に時間を要します。そのため、どこまで、何を確認するかということで神経を使う必要があります。そこで、アプリをどこまで確認するか、というところで少し雑にまとめてみます。 なお、ここの分け方は検証したいことと、その環境で雑に区分しています。 1. シナリオテスト ユーザが実際に操作する内容をシナリオに落とし込んで、期待されるシナリオを完遂できるか検証する ユーザの操作が変わるパターンはなるべく用意する モック/スタブサーバは利用しない 外部システムとの連携、端末の設定に依存する箇所も含む 2. 機能テスト(システム全体) サーバ側からの応答によりモバイルアプリケーションの振る舞いが変わる場合、それは可能な限り網羅する GUIからすると同じ表示でも、その裏側(サーバからの応答)が異なる場合も含む 機能として仕様に定義した範囲 モック/スタブサーバは利用しない 外部システムとの連携、端末の設定に依存する箇所も含む 3. 統合テスト サーバ側からの応答によりモバイルアプリケーションの振る舞いが変わる場合、それは可能な限り網羅する GUIからすると同じ表示でも、その裏側(サーバからの応答)が異なる場合も含む モック/スタブサーバを用意してでも、サーバからの通信結果をもとに、アプリが期待通り動作することを検証することが目的 端末の設定に依存する箇所を含む 4. GUIテスト レイアウトパターンはなるべく網羅する 同一レイアウトの使い回しに関しては、不要なものは実施しない ツールとテスト モバイルアプリでは、Headless browserのようなGUIの無い高速な確認手段は存在しません。また、espressoや、Debug用にSDKとしてハックしたライブラリを使う以外は、システムが提供するアニメーションなど含めてそれらを許容した上で各種テストを回す必要があります。 そのため、基本的にGUIから操作した上で確認を行う必要があるため実行速度はWebアプリほど速度を出すことが難しいです。一方、espressoなどのように限定した使い方であれば安定して高速に確認する手段もそろってきたので、そこらへんも解消する日が来るかもしれません。 シナリオテストやGUIテストを目的としたE2Eのテストを行う場合、基本的にAppiumのようなGUI越しに操作するツールを使うことになるでしょう。そこでは実行速度と安定性がやはりトレードオフになります。一方で、現在のモバイルアプリを検証するツールとしてはこれ以上の手段は殆どないです。 機能テストや統合テストを目的としたE2Eのテストを行うときの多くもAppiumのようなGUI越しに操作するツールが基本になると思います。ただ、espressoのような高速にView単体を確認できる手段も選択肢としてでてきました。そのため、単なる表示のバリエーションなんかはAppiumのようなもので実施するよりも、遥かに高速に実施できる環境として利用できるようになってきました。 ここで話している文脈における自動化されたテストは、手動テストによる回帰テストを減らすことが目的で使うことが多いと思います。なので、互いに補完関係になるように、プロジェクトとして十分な目的を選んでいきたいですね。…More
Appiumのテストを1台の計算機上で並列して実行させる
Appiumでテストを実行していると複数台の計算機でテストを並列して実行したい、と思う方もいるでしょう。 Appium自体はサーバなので、1台の計算機上で複数起動させ、テストを並列して実行させることができます。これを行えば、独立したテストケースを分散させて、それぞれのテストを実行、結果を収集するという簡単なテストケースの実行並列化もできます。Selenium Gridよりもかなり手軽にテストを実行できる環境になるでしょう。 設定する点は以下 Appiumサーバに必要な引数を与えて起動する テストケース側のcapabilityに対象となるAppiumサーバの待ち受けポートを指定する 例えば、appium_libを使っている人だとcapabilitiesのportに値を設定する必要があります。 例 Appiumサーバの起動 ※appiumコマンド箇所は、適切にnode .などに置き換えてください capabilityの指定 例えば、appium_libを使っていると、appium.textの[appium_lib]にportを指定する方法があったり( ★ )、以下のように直接メソッドに値を与えるならserver_capsに対して要素を指定する方法があります。 いずれにせよ、これによりシナリオをAppiumサーバに渡すことができるようになります。 並列実行 Step1 Step2 以下2種類でそれぞれ起動 注意点 iOSではiOS Simulatorの制限上、複数Simulatorを同時に起動させることができません。そのため、iOSは並列実行するには物理的に複数のMacマシンが必要です。 ref: https://github.com/appium/appium/blob/master/docs/en/appium-setup/parallel_tests.md ref: https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/server-args.mdMore
Appium 1.3.5 released
Appium 1.3.5 がリリースされましたね。 リリースノート https://github.com/appium/appium/releases/tag/v1.3.5 ここまでのバージョンになると、開発量も少し落ち着いてきたように見えます。 iOS8.x系に関しても、iOS7=>iOS8のような大きな変更がシミュレータにも入るわけではないので。 driver.get()でpageを取得できなかったところなんかの修正が入っています。あとはiOS8.2。 iOS8.3もbetaで入手できるようになりましたが、iOS8.3からは OS X 10.10以降がRequirementになります。 なので、メンテナンスされるメインストリームもOS X 10.10に移り変わる流れになりそうな予感。 Androidに関しては以下の修正が入っているので、1.3.4使っている人は更新したほうが良さそう。もとより、私の環境では1.3.4があまりちゃんと動かなかったので、masterブランチや1.3.5betaを使っていましたが、ここでnpmから入手できる正式版が使えるようになった。 add workaround for issue where UiAUtomator fails to find visible elements. fixed undefined member error for the release object.More