2

新しい Android アプリケーションの一部として、完全な継続的インテグレーションをセットアップしています (Jenkins を使用しますが、問題ありません)。

現在、JUnit と UI テストを自動化しており、追加の品質ステップとして、各ビルドの後に Monkey テストを追加することを考えていました。

しかし、Monkey に対する私たちのフィードバックは、今のところ非常に否定的です。新しく空の Android アプリケーション (Android Studio で空のプロジェクトを作成したときの基本的な Hello World アプリ) を作成しましたが、それでも、Monkey テストは定期的にクラッシュします (エミュレーターで実行されます)。私たちのアプリケーション。

私が試したコマンド:

adb shell monkey -v -v -s -2972043913753481246 -p my.app.package 50000

しかし、途中でクラッシュします (ステップ 6000 あたり)。

これは、エミュレーターが過度に要求していることが原因である可能性があると考えたため、エミュレーターが呼吸できるように調整を追加しました。

adb shell monkey -v -v -s -2972043913753481246 --throttle 150 -p my.app.package 50000

それでも、クラッシュします (さらに、ステップ 8000 あたり)。

もっと呼吸が必要かもと思ったので、念のため1秒のスロットリングを入れてみました(人間でもそれ以上の速さで行動できます)

adb shell monkey -v -v -s -2972043913753481246 --throttle 1000 -p my.app.package 50000

それでも、クラッシュします (ステップ 48 000 あたり)。

を追加して--ignore-native-crashesも何も変わりませんでした。

つまり、私の要点は次のとおりです。とにかくモンキーは本当に理にかなっていますか? 関連性がないようです (Android Studio 自体が提供する空の Hello World アプリが根本的な原因である場合、実際のアプリで何が起こるか見たくありません)。

Monkey のテストを安定させ、適切なものにする方法を見つけた人はいますか? どのような構成 (イベント数、スロットリング、追加フラグ) を使用していますか?

150 ミリ秒のスロットリングで発生するクラッシュの 1 つ:

// クラッシュ: com.android.launcher (pid 1838) // 短いメッセージ: java.lang.IllegalArgumentException // 長いメッセージ: java.lang.IllegalArgumentException: 幅と高さは > 0 でなければなりません // ビルド ラベル: generic_x86/sdk_google_phone_x86/ generic_x86:5.1/LKY45/1737576:eng/test-keys // Build Changelist: 1737576 // Build Time: 1423932217000 // java.lang.IllegalArgumentException: width and height must be > 0 // at android.graphics.Bitmap.createBitmap (Bitmap.java:810) // android.graphics.Bitmap.createBitmap(Bitmap.java:789) // android.graphics.Bitmap.createBitmap(Bitmap.java:756) // com.android.launcher2. Cling.dispatchDraw(Cling.java:201) // android.view.View.updateDisplayListIfDirty(View.java:14162) // android.view.View.getDisplayList(View.java:14189) // android.view .ViewGroup.recreateChildDisplayList(ViewGroup.java:3389) // android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3368) で // android.view.View.updateDisplayListIfDirty(View.java:14127) で // android.view.View で.buildLayer(View.java:13979) // com.android.launcher2.AppsCustomizeTabHost.enableAndBuildHardwareLayer(AppsCustomizeTabHost.java:359) // com.android.launcher2.AppsCustomizeTabHost.onLauncherTransitionStart(AppsCustomizeTabHost.java:403) // com.android.launcher2.Launcher.dispatchOnLauncherTransitionStart(Launcher.java:2538) // com.android.launcher2.Launcher.hideAppsCustomizeHelper(Launcher.java:2852) // com.android.launcher2.Launcher.showWorkspace(Launcher. java:2900) // com.android.launcher2.Launcher.showWorkspace(Launcher.java:2893) // com.android.launcher2.Launcher.startSearch(Launcher.java:1642) // com.android.launcher2.Launcher.onSearchRequested(Launcher.java:1766) // com.android.launcher2.Launcher.onKeyDown(Launcher.java:891) // Android .view.KeyEvent.dispatch(KeyEvent.java:2619) // android.app.Activity.dispatchKeyEvent(Activity.java:2707) で // com.android.launcher2.Launcher.dispatchKeyEvent(Launcher.java:1973) で / / com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:2276) // android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:4020) // android.view. ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3982) // android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544) で // android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597) // android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563) // android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3680) // android.view.ViewRootImpl $InputStage.apply(ViewRootImpl.java:3571) // android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3737) で // android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544) で / / android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597) // android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563) // android.view.ViewRootImpl$InputStage.apply( ViewRootImpl.java:3571) // android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544) で // android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597) // android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563) // android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3713) // android.view.ViewRootImpl$ImeInputStage .onFinishedInputEvent(ViewRootImpl.java:3874) // android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:2208) で // android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.java:1849) で / / android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.java:1840) // android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:2185) // android.view.InputEventSender.dispatchInputEventFinished( InputEventSender.java:141) // android.os.MessageQueue.nativePollOnce(Native Method) // android.os.MessageQueue.next(MessageQueue.java:143) // android.os.Looper.loop(Looper.java:122) // android.app.ActivityThread. main(ActivityThread.java:5257) // java.lang.reflect.Method.invoke(Native Method) // java.lang.reflect.Method.invoke(Method.java:372) // com.android. internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) // com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) で //android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) // com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) で //android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) // com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) で //

1000 ミリ秒のスロットリングで発生するクラッシュは、SO に投稿するには膨大な量 (数万行) になるのではないかと心配しています。

4

2 に答える 2

0

興味深いのは、モンキーは予測不可能で、次に何が起こるか分からないということです。Monkey はランダムなイベントを実行します。運が良ければ、順序なしですべてのイベントをトリガーし、いくつかの非表示、予期しない例外、またはアプリケーションの影響をポップアップ表示できます。

于 2015-08-27T09:05:56.830 に答える