Androidでの強力なAppiumテストを請求します





こんにちは、Habr!



私の名前はニコライ・アバロフです。 私はモバイルQAオートメーションチームとしてBadooのロンドンオフィスで働いています。 同僚のRajip Varmaが、Appiumのテストをより高速で信頼性の高いものにする方法について話しました。 以下は彼の記事の翻訳です。



近年、Appiumはモバイル開発で最も人気のある自動化ツールの1つになりました。 ただし、利点に加えて、特にテストコードがアプリケーションコードから完全に分離されているという事実に関連するいくつかの制限があります。 この記事では、Rajedipが、コードに超能力を与え、Androidのエンドツーエンドテストを自動化する際の最も厄介な問題を解決する方法について説明します。



問題番号1:不機嫌そうなアプリケーション





テストを実行すると、ポップアップメッセージがアプリケーションに表示されることを想像してください(左の図のように)。 メッセージの表示を制御するロジックがテスターの対象ではない場合はどうなりますか? この場合、テストの信頼性を確保するにはどうすればよいですか? または、アプリケーションで動くバナーをクリックしたいが、Appiumがクリックできるようになるまでにバナーの位置が変わったため、テストは失敗します!



テスト中のアプリケーション動作の予測不能性の多くの例があり、テストの失敗につながります。



あなたのテストがアプリケーションに伝えることができると想像してください:「私は今あなたをテストしているので、アプリケーションの評価を求めるポップアップメッセージを無効にしてください。」



問題番号2:Appiumはすべてをサポートしていません



このアプリケーションには、デバイスを振ることで、評価の拒否をキャンセルできる機能があります。



Appiumを使用してAndroidデバイスで揺れを自動化する方法は? Shakeエンドポイント((POST /セッション/:session_id / appium / device / shake)がありますが、UIAutomator2ドライバーには実装されていません。



そして、テストでアプリケーションに「デバイスが動揺したふりをする」ことがわかると想像してください。



解決策:バックドアを実装して、アプリケーションにテストを支援させます



バックドアは、自動化コードベース、つまりテストからAndroidアプリケーションのコードで定義されたメソッドを呼び出す方法です。



これを簡単な例で見てみましょう。 foo()



メソッドがあるとしましょう

アクティビティでは、 LoginActivity



クラスで次のようにします。







foo()



メソッドでは、ランダムなポップアップメッセージを無効にするコードを記述したり、偽のシェーキング機能やアプリケーションの状態を設定するものを追加したりできます。 次のようなものを使用して、オートメーションコードベースからこのメソッドを呼び出すことができると想像してください。







これで問題が解決します:「テストがアプリケーションに伝えることができることを想像してください...」



悪いニュース:すぐに使用できるAppiumでは、バックドアはサポートされていません。

良いニュース:バックドアはまだAppiumで実装できます!



ソリューションに移る前に、自動化でバックドアを使用する実例をいくつか示します。





PSすべてを自分で行うのは難しい場合があります。 私がこれをどのように行ったかに興味がない場合は、「プロジェクトのバックドアを使用したクイックスタート」の章に進んでください。



Appiumでのバックドアの実装





UIAutomator2サーバーの標準アーキテクチャ



  1. APK-1 => appium-uiautomator2-server-debug-androidTest.apk
  2. APK-2 => appium-uiautomator2-server.apk


APK-1はAPK-2のインストルメンテーションパッケージです。 テスト-計装テストがあります。 「adb shell am instrument ...」ドライバのコマンドによって実行されますこのテストの唯一の目的は、APK-2で定義されたHTTPサーバーを起動することです。



両方のAPKファイルは1つのプロセスで実行され、図では緑色で強調表示されています。



サーバーが稼働しているとき、クライアントはJSON-HTTP要求を送信でき、サーバーはそれらを実行します。



ただし、アーキテクチャを変更すると、Androidインスツルメンテーションを最大限に活用できます(以下を参照)。



変更されたUIAutomator2サーバーアーキテクチャ:





テスト対象のアプリの機能APK Appium



APK-2コードをAPK-1に注ぎました。 したがって、ツールテストとHTTPサーバーは同じAPKファイル内にあります。 それをマージ済みサーバーAPKと呼びましょう。



これで、新しいAPKファイルのManifest.xmlを変更して、ターゲットのインストルメント化されたパッケージがテストアプリケーションの名前のパッケージになるようにできます。



これは、 appium_instrumenterと呼ばれるRuby Gemを使用して簡単に実装できます。これは、 calabash -android gemのコードに基づいています。



次に、テスト対象のアプリケーションとしてキーストアを使用して、Merged Server APKに署名します。 これで、テスト対象のアプリケーションと同じプロセスで実行されているカスタムツールサーバーができました(緑色で強調表示)。



Merged Server APKを使用してアプリケーションをインスツルメントしました。つまり、後者はアプリケーションコンテキストにアクセスできます。 これは、Merged Server APKファイルに、アプリケーションで定義されたメソッドを呼び出すように依頼できることを意味します。



Merged Server APKにエンドポイントを作成して、呼び出すアプリケーションメソッドを示します。



/wd/hub/session/:sessionId/backdoor.







このエンドポイントで、呼び出すメソッドの名前を送信できます。 Merged Server APKはアプリケーションコンテキストを取得し、Java Reflection APIを使用してメソッドを呼び出します。



エンドポイントと統合されたこのAppium UIAutomator2サーバーバックドアのすべてのコードは、 リポジトリ 、「single_apk」ブランチからダウンロードできます。



次に、appium_uiautomator2_driverパッケージに付属のAPKファイルをカスタムAPKファイルに置き換えます。 最も難しいのは背後にあり、これらの操作は一度だけ行う必要があります。



テスト自動化コードには、バックドアメソッドを呼び出すための補助メソッドがあります。 Rubyの例を次に示します。







出来上がり! 超大国を得た! これで、Applicationクラスまたは現在のActivityクラスで定義されたパブリックメソッドを非常に簡単に呼び出すことができます。







同時に、テストコードが戻り値を取得することがサポートされています!



プロジェクトのバックドアのクイックスタート



1.のAppium UIAutomatorサーバーAPKを生成します

アプリケーション:





appium_instrumenter gem



設定します。 AppiumテストがJavaで記述されていても、Rubyのみでユーティリティを記述したため、一度だけ実行する必要があります。



 gem install appium_instrumenter appium_instrumenter instrument app-debug.apk
      
      





フォルダー./test_servers



が現在のディレクトリに作成されます。



 test_servers ├── appium-uiautomator2-server-debug-androidTest.apk └── appium-uiautomator2-server-v0.3.0.apk
      
      





上記の両方のAPKをデバイスにインストールします。



 adb install test_servers/appium-uiautomator2-server-debug-androidTest.apk adb install test_servers/appium-uiautomator2-server-v0.3.0.apk
      
      





2.フォークからappium_uiautomator2_driver



パッケージappium_uiautomator2_driver



インストールします。



 npm install “rajdeepv/appium-uiautomator2-driver#adb_host”
      
      





3. backdoor()



メソッドを定義します。



バックドアのエンドポイントにデータを送信するメソッドを定義します。



 http://localhost:#{APPIUM_FORWARDED_PORT}/wd/hub/session/:sessionId/backdoor
      
      





このメソッドの上記のRuby実装例を検討してください。 Javaまたは他の言語で記述する場合、同じメソッドを実装できます。



4.超大国があなたと共に来ますように!



トラブルを避ける



「大きな力には大きな責任が伴います。」



バックドアは非常に強力なツールです。 また、不適切に使用すると、不快な結果を招く可能性があります。 したがって、バックドアを使用してアプリケーションロジックを完全に変更すると、テストリスクはその値よりも高くなります。



バックドアを使用すると、以前は不可能だったシナリオを実装でき、テスト機能が拡張されます。 そして、場合によっては、それらなしではできません!



ここに物語があります。 ちなみに、4月1日、Rajedip ノボシビルスクのCodeFest講演しました。 彼のレポートのビデオは、夏にCodeFest YouTubeチャンネルとBadoo Techに掲載される予定です。



All Articles