40

EDIT: Updated description and error message and added some images. Still have this problem.

I have a strange error that occur many times when running espresso tests. After a couple of successful test runs the tests starts failing with following exception:

   06-23 13:04:48.438   info    TestRunner  failed: WhenNavigatingToReportsThenCorrectViewShouldBeShown(com.myapp.ui.views.MainActivityTest)
06-23 13:04:48.439  info    TestRunner  ----- begin exception -----
06-23 13:04:48.441  info    TestRunner  android.support.test.espresso.NoActivityResumedException: No activities in stage RESUMED. Did you forget to launch the activity. (test.getActivity() or similar)?
06-23 13:04:48.441  info    TestRunner  at dalvik.system.VMStack.getThreadStackTrace(Native Method)
06-23 13:04:48.441  info    TestRunner  at java.lang.Thread.getStackTrace(Thread.java:580)
06-23 13:04:48.441  info    TestRunner  at android.support.test.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:82)
06-23 13:04:48.441  info    TestRunner  at android.support.test.espresso.base.DefaultFailureHandler.handle(DefaultFailureHandler.java:53)
06-23 13:04:48.441  info    TestRunner  at android.support.test.espresso.ViewInteraction.runSynchronouslyOnUiThread(ViewInteraction.java:184)
06-23 13:04:48.441  info    TestRunner  at android.support.test.espresso.ViewInteraction.doPerform(ViewInteraction.java:115)
06-23 13:04:48.441  info    TestRunner  at android.support.test.espresso.ViewInteraction.perform(ViewInteraction.java:87)
06-23 13:04:48.441  info    TestRunner  at com.myapp.ui.views.MainActivityTest.WhenNavigatingToReportsThenCorrectViewShouldBeShown(MainActivityTest.java:96)
06-23 13:04:48.441  info    TestRunner  at java.lang.reflect.Method.invoke(Native Method)
06-23 13:04:48.441  info    TestRunner  at java.lang.reflect.Method.invoke(Method.java:372)
06-23 13:04:48.441  info    TestRunner  at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
06-23 13:04:48.441  info    TestRunner  at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
06-23 13:04:48.441  info    TestRunner  at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
06-23 13:04:48.441  info    TestRunner  at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
06-23 13:04:48.441  info    TestRunner  at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
06-23 13:04:48.441  info    TestRunner  at android.support.test.internal.statement.UiThreadStatement.evaluate(UiThreadStatement.java:55)
06-23 13:04:48.441  info    TestRunner  at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:257)
06-23 13:04:48.441  info    TestRunner  at org.junit.rules.RunRules.evaluate(RunRules.java:18)
06-23 13:04:48.441  info    TestRunner  at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
06-23 13:04:48.441  info    TestRunner  at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
06-23 13:04:48.441  info    TestRunner  at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
06-23 13:04:48.441  info    TestRunner  at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
06-23 13:04:48.441  info    TestRunner  at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
06-23 13:04:48.441  info    TestRunner  at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
06-23 13:04:48.441  info    TestRunner  at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
06-23 13:04:48.441  info    TestRunner  at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
06-23 13:04:48.441  info    TestRunner  at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
06-23 13:04:48.441  info    TestRunner  at org.junit.runners.Suite.runChild(Suite.java:128)
06-23 13:04:48.441  info    TestRunner  at org.junit.runners.Suite.runChild(Suite.java:24)
06-23 13:04:48.441  info    TestRunner  at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
06-23 13:04:48.441  info    TestRunner  at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
06-23 13:04:48.441  info    TestRunner  at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
06-23 13:04:48.441  info    TestRunner  at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
06-23 13:04:48.441  info    TestRunner  at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
06-23 13:04:48.441  info    TestRunner  at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
06-23 13:04:48.441  info    TestRunner  at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
06-23 13:04:48.441  info    TestRunner  at org.junit.runner.JUnitCore.run(JUnitCore.java:136)
06-23 13:04:48.441  info    TestRunner  at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:54)
06-23 13:04:48.441  info    TestRunner  at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:228)
06-23 13:04:48.441  info    TestRunner  at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1837)
06-23 13:04:48.441  info    TestRunner  ----- end exception -----
06-23 13:04:48.443  info    TestRunner  finished: WhenNavigatingToReportsThenCorrectViewShouldBeShown(com.myapp.ui.views.MainActivityTest)

I have a simple app with navigation to pages just containing text at this point, and the test should navigate to each page and identify this text.

@RunWith(AndroidJUnit4.class)
@LargeTest
public class MainActivityTest {

@Rule
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule(MainActivity.class);
private MainActivity mainActivity;

@Before
public void setActivity() {
    mainActivity = mActivityRule.getActivity();
}

 @Test
public void WhenNavigatingToReportsThenCorrectViewShouldBeShown() {
    onView(allOf(withId(R.id.icon), hasSibling(withText(R.string.reports)))).perform(click());

    onView(withText("This is the Reports Activity.")).check(matches(isDisplayed()));
    Spoon.screenshot(mainActivity, "main_view");
}
}

This failure only occurs on the real device. On emulated device the tests works fine. See images below.

All tests are executed by gradle script, starting with removing the previous app and test api, before installing it again. To ensure clean environment. The log indicates that uninstallation has been successful. Then deploying the new app and start running the tests. Now they fail.

If the tests have failed, it's not until I manually remove the app and the test api from device that I can get successful tests again. But only for a while until the same error occur.

Why do I get NoActivityResumedException, I can't find a good example of what it is and when it occurs.

Device overview with only physical device failing Failing tests

peuhse
  • 1,688
  • 2
  • 20
  • 32
  • 1
    I've seen other posts where they suggest switching of animations (in the Developers settings). – Pnemonic Aug 19 '15 at 09:55
  • have you found a solution? – piotrek1543 Jan 26 '16 at 17:45
  • 1
    Not a clear solution. But noticed that it often happens when a system window popup. Also when the activity expects a result. Found a couple of answers that might work for some problems: i.e. http://stackoverflow.com/questions/21703304/android-espresso-and-account-picker – peuhse Jan 27 '16 at 15:32
  • In my case as @Pnemonic pointed out, the animation is turned on. Hope this helps others. – Kim Montano Aug 02 '17 at 01:05
  • 1
    I have two android app modules in my project and I get this error randomly in different tests when run tests in all modules with single command (./gradlew spoon or ./gradlew connectedDebugAndroidTest), when I run tests only for particular module (./gradlew module1:connectedDebugAndroidTest) this error disappears. Don't know why – Kolchuga Sep 25 '17 at 20:17
  • I faced the same error, I was checking the bundle in Activity's onCreate() and if the bundle is null, in the else part I was calling finish(). So never call finish() during testing. Hope this helps someone. – Bhriguraj Salponia Oct 30 '18 at 06:31
  • @Kolchuga you need to add the `--no-parallel` after the command. Otherwise different tests will run on the same device making the tests flaky. – Sotti Jul 21 '19 at 01:25
  • I just caught this because my Android device was idled ("off"). C-; – Phlip Aug 20 '19 at 16:29

6 Answers6

80

I had the same problem. This happen when the screen on device is off. Turn screen on should fix the problem.

11

You can wake up your device before every test using Uiautomator.

@Before
public void init(){
     UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
     Point[] coordinates = new Point[4];
     coordinates[0] = new Point(248, 1520);
     coordinates[1] = new Point(248, 929);
     coordinates[2] = new Point(796, 1520);
     coordinates[3] = new Point(796, 929);
     try {
         if (!uiDevice.isScreenOn()) {
             uiDevice.wakeUp();
             uiDevice.swipe(coordinates, 10);
         }
     } catch (RemoteException e) {
         e.printStackTrace();
     }
}
Gordak
  • 2,060
  • 22
  • 32
2

Mainly the error is because if your connection is not in an active mode, it shouldn't be in sleep mode either it has to be in the app where the test cases have been written. Assuming you already used the @Rule Activity launch rule.

Ajinkya Dhote
  • 1,389
  • 3
  • 13
  • 26
1

In my case, the solution was to use the UI Automater

val uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
uiDevice.findObject(UiSelector().textContains("text")).click()

I wanted to do clicks on an activity hosted by google login SDK. I noticed the activity triggerred by SDK is still visible even when the process of the app under test is killed. So I used UI Automator which is inteded for cross-app functional UI testing

enter image description here

Islam Salah
  • 953
  • 11
  • 22
0

To avoid this, let your device stay awake. There is an option in the developer options of the device.

You could use com.android.ddmlib and a gradle task to change the device settings via adb for every build run and every device you are testing on.

import com.android.ddmlib.AndroidDebugBridge
import com.android.ddmlib.CollectingOutputReceiver
import com.android.ddmlib.IDevice
import com.android.ddmlib.NullOutputReceiver

task stayAwake {

    description = "Activate the Stay Awake settings in the developer options."
    group = "Device Setup"

    AndroidDebugBridge.initIfNeeded(false)
    def bridge = AndroidDebugBridge.createBridge(android.adbExecutable.path, false)

    doLast {
        bridge.devices.each {
            it.executeShellCommand("settings put global stay_on_while_plugged_in 3", NullOutputReceiver.receiver)
            println "Device ${it} will stay awake."
        }
    }
}

In addition you can activate the screen with another gradle task. (precondition is that no PIN or unlock pattern is set)

IDevice.metaClass.inputKeyEventByShell {
    delegate.executeShellCommand("input keyevent ${it}", NullOutputReceiver.receiver)
}
IDevice.metaClass.inputSwipeByShell {
    delegate.executeShellCommand("input swipe ${it}", NullOutputReceiver.receiver)
}

task unlockScreen {

    description = "Activate screen and unlock device."
    group = "Device Setup"

    AndroidDebugBridge.initIfNeeded(false)
    def bridge = AndroidDebugBridge.createBridge(android.adbExecutable.path, false)

    doLast {
        bridge.devices.each {

            def receiver = CollectingOutputReceiver.newInstance()
            it.executeShellCommand("dumpsys power | grep \"mHolding\"", receiver)

            def displaySuspendFalse = receiver.getOutput().find("mHoldingDisplaySuspendBlocker=false")
            def wakelockSuspendFalse = receiver.getOutput().find("mHoldingWakeLockSuspendBlocker")

            if (displaySuspendFalse || wakelockSuspendFalse) {
                it.inputKeyEventByShell('26') //power keyevent
                println "Screen of device $it activated & unlocked."
            }

            it.inputSwipeByShell('100 500 100 1450 100') //swipe action
        }
    }
}

Let these tasks run before your gradle task responsible for the UI tests.

This way no additional code in your tests is required to activate the devices and keeping them alive.

KraffMann
  • 322
  • 1
  • 4
  • 14
0

One possible cause of this is the tests are running in parallel. Use --no-parallel.

Example --> gradlew connectedLiveDebugAndroidTest --no-parallel

It this happens only when running all of them from the console or sequentially, but doesn't happen running them individually then chances are they are running on parallel o the same device. Two different Espresso tests running on the same device at the same time make them flaky and prone to fail.

Sotti
  • 14,089
  • 2
  • 50
  • 43