Обезьяна действительно значима?
В рамках нового приложения для Android мы настраиваем полную непрерывную интеграцию (с Jenkins, но это не имеет значения).
На данный момент мы автоматизировали тестирование JUnits и пользовательского интерфейса, и мы думали о добавлении тестирования Monkey после каждой сборки, просто в качестве дополнительного шага качества.
Однако наши отзывы об Обезьяне пока довольно негативные. Мы создали совершенно новое, пустое приложение Android (базовое приложение Hello World, когда вы создаете пустой проект в Android Studio), и даже тогда тест 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
ничего не изменилось.
Итак, весь мой смысл: действительно ли Monkey действительно имеет смысл? Это не имеет отношения к делу (если причиной является пустое приложение Hello World, предоставленное самой Android Studio, то я не хочу видеть, что произойдет с реальным приложением).
Кто-нибудь нашел способ сделать тестирование Monkey стабильным и актуальным? Какую конфигурацию (количество событий, регулирование, дополнительные флаги) вы используете?
Один из сбоев, который я получаю с удушением 150 мс:
// CRASH: com.android.launcher (pid 1838) // Short Msg: java.lang.IllegalArgumentException // Long Msg: java.lang.IllegalArgumentException: ширина и высота должны быть> 0 // Метка сборки: generic_x86/sdk_google_phone_x86/generic_x86:5.1/LKY45/1737576:eng/test-keys // Список изменений сборки: 1737576 // Время сборки: 1423932217000 // java.lang.IllegalArgumentException: ширина и высота должны быть> 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) // на андроид.view.View.buildLayer(View.java:13979) // на com.android.launcher2.AppsCustomizeTabHost.enableAndBuildHardwareLayer(AppsCustomizeTabHost.java:359) // на com.android.launcher2.AppsCustomizeTabHost.onLauncherTransitionStost //H.android.launcher2.Launcher.dispatchOnLauncherTransitionStart(Launcher.java:2538) // на com.android.launcher2.Launcher.hideAppsCustomizeHelper(Launcher.java:2852) // на com.android.launcher2.Launcher.showork: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) // на андроид.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) // at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:4020) // at android.view.ViewRootImpl$ViewPostImeInmpl.jpg (). // at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544) // at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597) // на входе android.view.ViewRootImpwardS $ (ViewRootImpl.java:3563) // на android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3680) // на android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571) // на андроид.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3737) // at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544) // at android.view.ViewRootImpl$InputStage.onImpl. 3597) // at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563) // at 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.forward (ViewRootImpl.java:3563) // на android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3713) // на android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImp74) //74). android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:2208) // at android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.jroidInhoput.ventInventput.putInvent.ventinput.putInvent.put.ventinvent.put.ventInput.put.ventInput.ventinvent.put. InputMethodManager.java:1840) // at android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:2185) // at android.view.InputEventSender.dispatchInputEava.vent.vent1vent_vent.vent1) at1.MessageQueue.nativePollOnce(Родной метод) // на андро id.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(собственный метод) // в java.lang.reflect.Method.invoke(Method.java:372) // в com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) // at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) //
Боюсь, что авария с дросселированием в 1000 мс - это путь к огромным (десятки тысяч строк) публикациям на SO.
2 ответа
Интересно, что Обезьяна непредсказуема, вы никогда не знаете, что будет дальше. Обезьяна выполняет случайные события, и, если повезет, она может инициировать все события без какого-либо порядка, а затем выдает некоторые скрытые неожиданные исключения или эффекты в приложении.
Я считаю, что ответ "да" на вопрос "является ли тест обезьяны значимым". Как вы уже упоминали, проблема может быть связана с ошибкой эмулятора. И я предполагаю, что ваша команда тестирования обезьяны ограничена в вашем приложении, и все настройки в порядке.
И выпрыгнув из этой ошибки, вы можете увидеть, что тест на обезьяну является своего рода стресс-тестированием. Это может идентифицировать некоторые из готовых ошибок. И есть несколько причин, я беру из вики:
- Собственная случайность тестирования на обезьянах также делает его хорошим способом найти серьезные ошибки, которые могут сломать всю систему.
- Умные обезьяны, если их правильно настроить с помощью точной модели состояния, могут быть действительно хороши в поиске различных видов ошибок.
Таким образом, тест обезьяны как часть тестирования программного обеспечения необходим. И если вы хотите, чтобы ваша обезьяна стала "умной". Вы можете использовать monkeyrunner, предоставленный Google, чтобы указать какое-либо событие и вручную протестировать часть вашего приложения. Monkeyrunner может быть немного стабильным и актуальным. Вот несколько советов и приемов, которые я использовал в тесте Android на обезьян.