paint-brush
モバイルデバイスで毎日 5000 件以上のテストを実行する方法; InDrive のプレイブックより (パート 1)@indrivetech
18,915 測定値
18,915 測定値

モバイルデバイスで毎日 5000 件以上のテストを実行する方法; InDrive のプレイブックより (パート 1)

inDrive.Tech10m2023/05/30
Read on Terminal Reader

長すぎる; 読むには

InDrive は、iOS デバイスと Android デバイスを合わせて 1 日あたり 5,000 件以上のテストを実行します。秘密は単純です。Selenoid を使用したからです。 Appium テストを作成するには、次のものを使用します。 Kotlin; JUnit 5;メイブン。私たちは、資料を 2 つのパートに分割するのが良いと考えました。1 つ目は Android に焦点を当て、2 つ目は iOS に焦点を当てました。
featured image - モバイルデバイスで毎日 5000 件以上のテストを実行する方法; InDrive のプレイブックより (パート 1)
inDrive.Tech HackerNoon profile picture

こんにちは、みんな!私の名前はタラス・エゴロフです。私はinDriveのエンジニアです。 iOS デバイスと Android デバイスを合わせて 1 日あたり 5,000 件を超えるテストを実行できるインフラストラクチャをどのようにセットアップしたかを説明します。秘密は単純です。Selenoid を使用したからです。

序文

昨年、私たちの同僚は自動テストの研究を実施し、私たちはその研究の一環としてアンケートに参加しました。

調査対象チームのうち、Appium は約 20% のチームで使用されており、これは悪いスタートではありません。


私たちは調査結果に満足していたので、私たちの経験を皆さんと共有し、アドバイスを得るために記事を書くことにしました。私たちは、資料を 2 つのパートに分割するのが良いと考えました。1 つ目は Android に焦点を当て、2 つ目は iOS に焦点を当てました。


まずは Android から始めましょう。

Android でテストを実行する

Selenoid は、Docker コンテナーでブラウザーや Android エミュレーターを実行および管理するための一般的なツールです。詳細については、ドキュメントを参照してください。


Appium テストを作成するには、以下を使用します。

  • コトリン。
  • JUnit 5;
  • メイブン。

最初の走行。セレノイドの設定

  1. browsers.json構成ファイルを作成します。


 {  "android": {    "default": "10.0",    "versions": {      "10.0": {        "image": "browsers/android:10.0",        "port": "4444",        "path": "/wd/hub"      }    }  } }


エミュレータイメージはimageで指定されます。 aerokubeの人たちは、Android エミュレータの既製のイメージを用意しました。ここまたはここ で確認できます。画像は互いに何の違いもありません。


例として、画像browsers/android:10.0を見てみましょう。イメージは事前にダウンロードする必要があります: docker pull browsers/android:10.0 。そうしないとテストは実行されません。


 Original error: create container: Error response from daemon: No such image: browsers/android:10.0


  1. 次のステップは、Selenoid を実行することです。これはdockerを介して直接行うことも、 Configuration Managerを使用するオプションもあります。


 docker run -d \           -v /var/run/docker.sock:/var/run/docker.sock \           -v "$(pwd)/selenoid/config/":/etc/selenoid/:ro \           -p 4444:4444 \           --name selenoid \           aerokube/selenoid:1.10.7


ブラウザでhttp://localhost:4444のリンクをクリックすると、Selenoid が適切に動作しているかどうかを確認できます。


 You are using Selenoid 1.10.7!


  1. ドライバーの Appium テストで Selenoid アドレスを指定します。


 ... val driver = AndroidDriver(URL("http://localhost:4444/wd/hub"), capabilities) ...


  1. 次に、ビルドイン機能へのリンクを指定します。


 ... capabilities.setCapability("appium:app", "https://storage.example.com/builds/app.apk") ...


リンクを提供できない場合は、ビルドへのパスを指定できます:**


 ... capabilities.setCapability("appium:app", "/builds/app.apk") ...


/builds/app.apkは、エミュレータが実行されているコンテナ内のパスです。このオプションが適切に機能するには、 browsers.jsonvolumes必ず指定してください。


 {  "android": {    "default": "10.0",    "versions": {      "10.0": {        ...        "volumes": [          "/home/username/app.apk:/builds/app.apk:ro"        ]        ...      }    }  } }


/home/username/app.apkホスト プラットフォーム上のビルドへのパスです。


これで Selenoid のセットアップがほぼ完了したので、テストを実行してみましょう。


 ./mvnw test


ただし、残念ながらテストは実行できません。これを調べて、何が問題なのか見てみましょう。

2回目の走行。ログとビデオを見てみる

起動に失敗した後に最初に行うことは、Selenoid ログを確認することです。


 docker logs selenoid


 [INIT] [Loading configuration files...] [INIT] [Loaded configuration from /etc/selenoid/browsers.json] [INIT] [Video Dir: /opt/selenoid/video] [INIT] [Your Docker API version is 1.41] [INIT] [Timezone: UTC] [INIT] [Listening on :4444] [NEW_REQUEST] [unknown] [172.17.0.1] [NEW_REQUEST_ACCEPTED] [unknown] [172.17.0.1] [LOCATING_SERVICE] [android] [10.0] [USING_DOCKER] [android] [10.0] [CREATING_CONTAINER] [selenoid/android:10.0] [STARTING_CONTAINER] [selenoid/android:10.0] [75e454341da7fc4b58ba104a5180813bac6cd7c124037a759b6c976e65b168fa] [CONTAINER_STARTED] [selenoid/android:10.0] [75e454341da7fc4b58ba104a5180813bac6cd7c124037a759b6c976e65b168fa] [0.40s] [0] [REMOVING_CONTAINER] [75e454341da7fc4b58ba104a5180813bac6cd7c124037a759b6c976e65b168fa] [0] [CONTAINER_REMOVED] [75e454341da7fc4b58ba104a5180813bac6cd7c124037a759b6c976e65b168fa] [0] [SERVICE_STARTUP_FAILED] [http://172.17.0.3:4444/wd/hub does not respond in 30s]


ステータスが SERVICE_STARTUP_FAILED であることがわかります。ドキュメントにアクセスしてステータス値を確認してください。


 SERVICE_STARTUP_FAILED - Failed to start Docker container or driver binary


このエラーからは多くのことはわかりません。さらに詳しい情報が必要です。コンテナのログを確認してみると良いでしょう。ロギングを有効にしてこれを実行しましょう。


 docker run -d \           -p 4444:4444 \           -v /var/run/docker.sock:/var/run/docker.sock \           -v "$(pwd)/selenoid/config/":/etc/selenoid/:ro \           -v "$(pwd)/selenoid/logs/":/opt/selenoid/logs/ \           aerokube/selenoid:1.10.7 \           -log-output-dir /opt/selenoid/logs


また、「機能」セクションでログを有効にします。


 ... capabilities.setCapability("enableLog", true) ...


テストを実行し、ブラウザhttp://localhost:4444/logs/を使用してログを確認します。


 2023-04-16T13:44:43.909768530Z Waiting X server... 2023-04-16T13:44:44.009494775Z Logging to: /tmp/fluxbox.log 2023-04-16T13:44:44.047587277Z Waiting X server... 2023-04-16T13:44:44.151933325Z Waiting X server... 2023-04-16T13:44:44.262850410Z * daemon not running; starting now at tcp:5037 2023-04-16T13:44:44.457972956Z * daemon started successfully 2023-04-16T13:44:44.458249266Z adb: no devices/emulators found 2023-04-16T13:44:45.463480812Z adb: no devices/emulators found 2023-04-16T13:44:46.471547723Z adb: no devices/emulators found 2023-04-16T13:44:47.476093515Z adb: no devices/emulators found 2023-04-16T13:44:48.481987351Z adb: no devices/emulators found 2023-04-16T13:44:49.486503149Z adb: no devices/emulators found 2023-04-16T13:44:50.492757801Z adb: no devices/emulators found 2023-04-16T13:44:51.499094108Z adb: no devices/emulators found 2023-04-16T13:44:52.505862428Z adb: no devices/emulators found 2023-04-16T13:44:53.513276412Z adb: no devices/emulators found 2023-04-16T13:44:54.520642210Z adb: no devices/emulators found 2023-04-16T13:44:55.527420189Z adb: no devices/emulators found 2023-04-16T13:44:56.534631013Z adb: no devices/emulators found 2023-04-16T13:44:57.316094939Z WARNING. Using fallback path for the emulator registration directory. 2023-04-16T13:44:57.335415397Z checkValid: hw configs not eq 2023-04-16T13:44:57.541959741Z adb: device offline 2023-04-16T13:44:58.547907700Z adb: device offline 2023-04-16T13:44:58.565504866Z emulator: WARNING: System image is writable 2023-04-16T13:44:58.565528396Z emulator: Cold boot: different AVD configuration 2023-04-16T13:44:58.565532576Z Your emulator is out of date, please update by launching Android Studio: 2023-04-16T13:44:58.565536346Z - Start Android Studio 2023-04-16T13:44:58.565539506Z - Select menu "Tools > Android > SDK Manager" 2023-04-16T13:44:58.565543076Z - Click "SDK Tools" tab 2023-04-16T13:44:58.565546216Z - Check "Android Emulator" checkbox 2023-04-16T13:44:58.565549216Z - Click "OK" 2023-04-16T13:44:58.565552146Z 2023-04-16T13:44:59.554451514Z adb: device offline 2023-04-16T13:45:00.560926060Z adb: device offline 2023-04-16T13:45:01.568777440Z adb: device offline 2023-04-16T13:45:12.124226047Z emulator: INFO: boot completed 2023-04-16T13:45:12.124251007Z emulator: INFO: boot time 27848 ms 2023-04-16T13:45:12.124255077Z emulator: Increasing screen off timeout, logcat buffer size to 2M. 2023-04-16T13:45:12.152557294Z emulator: Revoking microphone permissions for Google App.


Appium ログは表示されないため、ここでもコンテナ ログはあまり役に立ちません。それでは、それらを有効にしてみましょう。これを行うには、スクリプトのエントリ point.shを見てみましょう。


 ... if [ -z "$VERBOSE" ]; then APPIUM_ARGS="$APPIUM_ARGS --log-level error" else EMULATOR_ARGS="$EMULATOR_ARGS -verbose" fi ...


Appium ログを有効にするには、パラメータVERBOSE=trueおよびAPPIUM_ARGS=--log-level debug : をコンテナに渡す必要があります。


 {  "android": {    "default": "10.0",    "versions": {      "10.0": {        ...        "env": [          "VERBOSE=true",          "APPIUM_ARGS=--log-level debug"        ]        ...      }    }  } }


Appium でログをデバッグできるようにするには、VERBOSE を渡す必要があります。この場合、エミュレータのログがオンになり、「エーテル」の充填が開始されます。」 しかし、将来のイメージのためにそれを修正しました =)


これで、 APPIUM_ARGS=-log-level debugに渡すだけで十分です。


 ... [HTTP] --> POST /wd/hub/session/c89fa9c2-ca2b-49cd-ab31-590eeccf77d1/element [HTTP] {"using":"id","value":"authorization_edittext_phone"} [debug] [W3C (c89fa9c2)] Calling AppiumDriver.findElement() with args: ["id","authorization_edittext_phone"," c89fa9c2-ca2b-49cd-ab31-590eeccf77d1"] [debug] [BaseDriver] Valid locator strategies for this request: xpath, id, class name, accessibility id, -and roid uiautomator [debug] [BaseDriver] Waiting up to 0 ms for condition [debug] [WD Proxy] Matched '/element' to command name 'findElement' [debug] [WD Proxy] Proxying [POST /element] to [POST http://127.0.0.1:8200/wd/hub/session/65943f03-3b35-4d3eb221-d6dc7988f935/element] with body: {"strategy":"id","selector": "authorization_edittext_phone","context":"","multiple":false} [WD Proxy] Got response with status 404: {"sessionId":"65943f03-3b35-4d3e-b221-d6dc7988f935","value":{"error" :"no such element","message":"An element could not be located on the page using the given search parameters","stacktrace":"io.appium.uiautomator2.common.exceptions.El ementNotFoundException: An element could not be located on the page using the given search parameters\n\tat io.appium.uiautomator2.handler.FindElement.safeHandle(Find Element.java:73)\n\tat io.appium.uiautomator2.handler.request.SafeRequestHandler.handle(SafeRequestHandler.java:41)\n\tat io.appium.uiautomator2.server.AppiumServlet. handleRequest(AppiumServlet.java:253)\n\tat io.appium.uiautomator2.server.AppiumServlet.handleHttpRequest(AppiumServlet.java:247)\n\tat io.appium.uiautomator2.http.Se rverHandler.channelRead(ServerHandler.java:68)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)\n\tat io .netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)\n\tat io.netty.chann... [debug] [W3C] Matched W3C error code 'no such element' to NoSuchElementError [debug] [W3C (c89fa9c2)] Encountered internal error running command: NoSuchElementError: An element could not be located on the page using the given search parameters. [debug] [W3C (c89fa9c2)] at AndroidUiautomator2Driver.findElOrEls (/opt/node_modules/appium/node_modules/appium-android-driver/lib/commands/find.js:75:11) [debug] [W3C (c89fa9c2)] at process._tickCallback (internal/process/next_tick.js:68:7) [HTTP] <-- POST /wd/hub/session/c89fa9c2-ca2b-49cd-ab31-590eeccf77d1/element 404 23 ms - 444 ...


ログからわかるように、Appium は要素を見つけることができません。エミュレータ画面で何が起こっているのか見てみましょう。これを行うには、Selenoid UI を実行する必要があります。


 docker run -d \           --name selenoid-ui \           -p 8080:8080 \           --link selenoid:selenoid \           aerokube/selenoid-ui:1.10.4 \           --selenoid-uri "http://selenoid:4444"


http://0.0.0.0:8080に移動し、Selenoid UI を開きます。


Selenoid UI は次のようになります


テストでは必ず VNC とビデオ録画を有効にしてください。


 ... capabilities.setCapability("enableVNC", true) capabilities.setCapability("enableVideo", true) ...


Selenoid 起動コマンドは次のようになります。


 docker run -d \ -v /var/run/docker.sock:/var/run/docker.sock \ -v "(pwd)/selenoid/logs/":/opt/selenoid/logs/ \ -v /opt/selenoid/video/:/opt/selenoid/video/ \ -e OVERRIDE_VIDEO_OUTPUT_DIR="/opt/selenoid/video/" \ -p 4444:4444 \ -name selenoid \ aerokube/selenoid:1.10.7 \ -log-output-dir /opt/selenoid/logs


テストが起動して実行されたら、Selenoid UI を開きます。


Selenoid UI の起動プロセスは次のようになります。


VNC とログ


そして、これがそのビデオです。


起動エラーの原因が判明しました。素晴らしい!次へ移りましょう。

3回目の走行。エミュレータイメージの構築

結局のところ、Selenoid エミュレータのイメージは Google Play サービスなしでは動作しません。この状況を解決するには、エミュレータ イメージを自分で構築する必要があります。 aerokube のスタッフは、写真とドキュメントを含むリポジトリなど、これに必要なものをすべてまとめてくれました。


  1. リポジトリをダウンロードしています
  2. seleniumフォルダーに移動します。
  3. スクリプト./automate_android.shを実行し、質問に答えます。私たちの場合は次のようになります。


 Specify Appium version: [1.18.1] >> 1.18.1 Specify Android image type (possible values: "default", "google_apis", "google_apis_playstore", "android-tv", "android-wear"): [default] >> google_apis Specify Application Binary Interface (possible values: "armeabi-v7a", "arm64-v8a", "x86", "x86_64"): [x86] >> x86 Specify Android version: [8.1] >> 10.0 Specify device preset name if needed (eg "Nexus 4"): >> Specify SD card size, Mb: [500] >> Specify userdata.img size, Mb: [500] >> Are you building a Chrome Mobile image (for mobile web testing): [n] >> y Specify Chromedriver version if needed (required for Chrome Mobile): >> 74.0.3729.6 Specify image tag: [selenoid/chrome-mobile:74.0] >> android-emulator:10.0 Add Android quick boot snapshot? [y] >> n


「Android クイック ブート スナップショットを追加しますか?」という質問を見たとき、これはエミュレータスナップショットだと思いました。しかし、コードを見ると、APK アプリケーションをインストールするために必要なスクリプトを呼び出しています。基本的に、それは私たちに何の利益も与えません。


コンテナの起動を高速化するためにすでにスナップショット エミュレータを使用していますが、それについては他の記事で説明します。


  1. イメージが構築されると、それをレジストリにプッシュするように求められます。まだ必要ではないため、この申し出はお断りさせていただきます。


 Push? >> n


Google Play サービスを使用してビルドをまとめました。忘れずに、browsers.json の image パラメータを変更し、Selenoid を再起動してください。


次に、テストを再実行してみましょう。


 [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------


そして、こちらが試運転の動画です


総括する

私たちが行ったこと:


  • Android テストを実行するように Selenoid を構成しました。
  • ログとビデオを確認してトラブルシューティングを行う方法を学びました。
  • Google Play サービスを使用して独自のエミュレータ イメージを構築しました。


他にお伝えしたいこと:


  • セレノイドのタイムアウト。アプリが大きい場合、タイムアウトに関する問題が発生する可能性があります。
  • コンテナーの実行を高速化する方法を試した方法。ビデオでは、実行に約 1 分ほどかかることが示されています。
  • Espresso で書かれたネイティブ Android テストを Selenoid 上で実行してみた方法。ネタバレ注意:これはうまくいきます!


一方、次のパートでは、インフラストラクチャをスケールアップし、iOS でテストを実行した方法について説明します。