Тесты Flaky Espresso: тест не проходит по таймауту после запуска действия.

После запуска занятия мой тест эспрессо не проходит с таймаутом через 45 секунд.

Для запуска активности я использую InstrumentationRegistry.getInstrumentation().startActivitySync(intent). Несмотря на то, что действие запускается правильно, тест выдает ошибку тайм-аута через 45 секунд. Это случается только изредка.

Обратите внимание, что мое приложение получает некоторые данные через OkHTTP сразу после запуска действия. Я также использую библиотеки, такие как Firebase Event Logging. Однако я могу подтвердить, что все запросы OkHTTP выполняются в течение 2-3 секунд.

Каковы возможные причины, по которым эспрессо не может завершить тест? Как я могу отладить эту проблему?

Вот трассировки стека при истечении времени ожидания:

  Thread[Jit thread pool worker thread 0,5,main]

  Thread[arch_disk_io_3,5,main]
    sun.misc.Unsafe.park(Native Method)
    java.util.concurrent.locks.LockSupport.park(LockSupport.java:190)
    java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2067)
    java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
    java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1092)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1152)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    java.lang.Thread.run(Thread.java:919)

  Thread[AsyncTask #1,5,main]
    sun.misc.Unsafe.park(Native Method)
    java.util.concurrent.locks.LockSupport.park(LockSupport.java:190)
    java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:459)
    java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
    java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
    java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1092)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1152)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    java.lang.Thread.run(Thread.java:919)

  Thread[Okio Watchdog,5,main]
    java.lang.Object.wait(Native Method)
    okio.AsyncTimeout.awaitTimeout(AsyncTimeout.java:361)
    okio.AsyncTimeout$Watchdog.run(AsyncTimeout.java:312)

  Thread[Timer-1,5,main]
    java.lang.Object.wait(Native Method)
    java.lang.Object.wait(Object.java:442)
    java.util.TimerThread.mainLoop(Timer.java:559)
    java.util.TimerThread.run(Timer.java:512)

  Thread[OkHttp ConnectionPool,5,main]
    java.lang.Object.wait(Native Method)
    com.android.okhttp.ConnectionPool$1.run(ConnectionPool.java:106)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    java.lang.Thread.run(Thread.java:919)

  Thread[RenderThread,7,main]

  Thread[HeapTaskDaemon,5,system]

  Thread[queued-work-looper,5,main]
    android.os.MessageQueue.nativePollOnce(Native Method)
    android.os.MessageQueue.next(MessageQueue.java:336)
    android.os.Looper.loop(Looper.java:174)
    android.os.HandlerThread.run(HandlerThread.java:67)

  Thread[hwuiTask1,6,main]

  Thread[ReferenceQueueDaemon,5,system]
    java.lang.Object.wait(Native Method)
    java.lang.Object.wait(Object.java:442)
    java.lang.Object.wait(Object.java:568)
    java.lang.Daemons$ReferenceQueueDaemon.runInternal(Daemons.java:215)
    java.lang.Daemons$Daemon.run(Daemons.java:137)
    java.lang.Thread.run(Thread.java:919)

  Thread[pool-1-thread-1,5,main]
    sun.misc.Unsafe.park(Native Method)
    java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:230)
    java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2109)
    java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1132)
    java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:849)
    java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1092)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1152)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    java.lang.Thread.run(Thread.java:919)

  Thread[OkHttp ConnectionPool,5,main]
    java.lang.Object.wait(Native Method)
    okhttp3.ConnectionPool$1.run(ConnectionPool.java:67)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    java.lang.Thread.run(Thread.java:919)

  Thread[pool-5-thread-2,5,main]
    sun.misc.Unsafe.park(Native Met

Теперь я смог обойти проблему, вставив InstrumentationRegistry.getInstrumentation().startActivitySync(intent) в несколько мест в моем коде предварительного условия (перед запуском тестируемого действия).


person Mike76    schedule 18.10.2019    source источник
comment
В моем понимании IdlingResources - это средство сказать Espresso ждать определенного ресурса. Смысл в том, чтобы избежать необходимости в Thread.sleep (). Однако проблема не в том, чтобы дождаться ресурса. Это противоположная проблема: кажется, что эспрессо ждет ресурс, который не простаивает.   -  person ponkape    schedule 18.10.2019
comment
Совершенно верно. И речь не идет об анимации, может быть, можно попробовать другой экземпляр сервера? Это только конкретная деятельность?   -  person Mike76    schedule 18.10.2019
comment
Анимации нет. Сейчас я начну поэтапно отключать определенные функции. Однако мне бы очень хотелось извлечь отладочную информацию из Espresso, не раскручивая мою собственную версию Espresso.   -  person ponkape    schedule 18.10.2019
comment
E / TestRunner: не удалось: registerWithoutUI (com.myapp.RegistrationTests) ----- начало исключения ----- E / TestRunner: java.lang.RuntimeException: не удалось запустить намерение Intent {act = android.intent .action.MAIN flg = 0x14000000 cmp = com.myapp / com.myapp.navigation.StartupActivity} в течение 45000 секунд. Возможно, основной поток не простаивал в течение разумного промежутка времени? Может быть анимация или что-то постоянно перекрашивающее экран. Или действие выполняет сетевые вызовы при создании? См. Журналы дампов потоков. Для справки, последний раз, когда очередь событий простаивала перед вашим запросом на запуск действия, было 1571388177991, а теперь последний раз, когда очередь простаивала, было: 1571388191468. Если эти числа совпадают, ваша деятельность может забивать очередь событий. в androidx.test.runner.MonitoringInstrumentation.startActivitySync (MonitoringInstrumentation.java:483) в com.myapp.TestUtilKt.launchActivity (TestUtil.kt: 25) в com.myapp.RobotKitKt.launchStartupActivity (RobotKit.kt: 18 ) по адресу com.myappe.RobotKitKt.precondition_new_registration (RobotKit.kt: 163) по адресу com.myapp.RegistrationTests.registerWithoutUI (RegistrationTests.kt: 48) по адресу java.lang.reflect.Method.invoke (собственный метод) в org.junit. runners.model.FrameworkMethod $ 1.runReflectiveCall (FrameworkMethod.java:50) в org.junit.internal.runners.model.ReflectiveCallable.run (ReflectiveCallable.java:12) в org.junit.runners.model.FrameworkMetvoke .java: 47) на org.junit.internal.runners.statements.InvokeMethod.evaluate (InvokeMethod.java:17) на androidx.test.internal.runner.junit4.statement.RunBefores.evaluate (RunBefores.java:80) на org.junit.runners.ParentRunner.runLeaf (ParentRu nner.java:325) в org.junit.runners.BlockJUnit4ClassRunner.runChild (BlockJUnit4ClassRunner.java:78) в org.junit.runners.BlockJUnit4ClassRunner.runChild (BlockJUnit.runner.java.Runner.java: run (ParentRunner.java:290) в org.junit.runners.ParentRunner $ 1.schedule (ParentRunner.java:71) в org.junit.runners.ParentRunner.runChildren (ParentRunner.java:288) в org.junit.runners. ParentRunner.access $ 000 (ParentRunner.java:58) на org.junit.runners.ParentRunner $ 2.evaluate (ParentRunner.java:268) на org.junit.runners.ParentRunner.run (ParentRunner.java:363) на androidx.test .ext.junit.runners. AndroidJUnit4.run (AndroidJUnit4.java:104) на org.junit.runners.Suite.runChild (Suite.java:128) на org.junit.runners.Suite.runChild (Suite.java:27) на org.junit.runners .ParentRunner $ 3.run (ParentRunner.java:290) на org.junit.runners.ParentRunner $ 1.schedule (ParentRunner.java:71) на org.junit.runners.ParentRunner.runChildren (ParentRunner.java:288) на org. junit.runners.ParentRunner.access $ 000 (ParentRunner.java:58) на org.junit.runners.ParentRunner $ 2.evaluate (ParentRunner.java:268) на org.junit.runners.ParentRunner.run (ParentRunner ).java:36 на org.junit.runner.JUnitCore.run (JUnitCore.java:137) на org.junit.runner.JUnitCore.run (JUnitCore.java:115) на androidx.test.internal.runner.TestExecutor.execute (TestExecutor.execute.javaExecutor. : 56) в androidx.test.runner.AndroidJUnitRunner.onStart (AndroidJUnitRunner.java:392) в android.app.Instrumentation $ InstrumentationThread.run (Instrumentation.java:2189) ---- - конец исключения -----   -  person Mike76    schedule 19.10.2019


Ответы (1)


Мне жаль, что у меня не было времени углубиться в эспрессо, чтобы помочь исправить весь этот беспорядок.

Вы используете IdlingResrouces? Thread.sleep() теперь поддерживается IdlingResources. Найдите это, если бы это могло правильно обработать вызов и не умерло бы из-за тайм-аута.

person Mike76    schedule 21.10.2019