'No activities found. Did you forget to launch the activity by calling getActivity() or startActivitySync or similar

When start my android app first start FirstActivity. When I click button on FirstActivity than start AddTraderActivity. If I press button "START REQUEST" in AddTraderActivity then I call:

setResult(RESULT_OK);
finish();

As result AddTraderActivity is destroy and show FirstActivity. Nice.

Now I want to write Espresso's tests for AddTraderActivityTest . Here tests:

@RunWith(AndroidJUnit4::class)
@SmallTest
class AddTraderActivityTest {

    @get:Rule
    var addTraderActivity: IntentsTestRule<AddTraderActivity> =
        IntentsTestRule(AddTraderActivity::class.java)

    @Test
    fun toolBarHeight() {
        onView(withId(R.id.toolBar))
            .check(matches(withHeightResId(R.dimen.tool_bar_height)))
    }

    @Test
    fun buttonStartTextUppercase() {
        onView(withId(R.id.startButton))
            .check(matches(withTextUppercaseResId(R.string.start)))
    }
}

As result when I start this tests, then start ONLY AddTraderActivity and tests success pass. Nice.

Now I want to write test for click on button "START REQUEST"

Here test:

@Test
fun pressButtonStartProgressBarDisplayed() {
    onView(withId(R.id.baseTextInputEditText)).perform(typeText("BASE_TEST"))
    onView(withId(R.id.quoteTextInputEditText)).perform(typeText("QUOTE_TEST"))
    onView(withId(R.id.startButton)).perform(click())

    onView(withId(R.id.containerProgressBarLayout)).check(matches(isDisplayed()))
}

As result when test run and press button "START REQUEST" I get the next error:

Testing started at 16:05 ...

$ adb shell am instrument -w -r   -e debug false -e class 'com.myproject.AddTraderActivityTest#pressButtonStartProgressBarDisplayed' com.myproject.debug.test/androidx.test.runner.AndroidJUnitRunner
Client not ready yet..
Started running tests

java.lang.RuntimeException: No activities found. Did you forget to launch the activity by calling getActivity() or startActivitySync or similar?
at androidx.test.espresso.base.RootViewPicker.waitForAtLeastOneActivityToBeResumed(RootViewPicker.java:169)
at androidx.test.espresso.base.RootViewPicker.get(RootViewPicker.java:83)
at androidx.test.espresso.ViewInteractionModule.provideRootView(ViewInteractionModule.java:77)
at androidx.test.espresso.ViewInteractionModule_ProvideRootViewFactory.provideRootView(ViewInteractionModule_ProvideRootViewFactory.java:35)
at androidx.test.espresso.ViewInteractionModule_ProvideRootViewFactory.get(ViewInteractionModule_ProvideRootViewFactory.java:24)
at androidx.test.espresso.ViewInteractionModule_ProvideRootViewFactory.get(ViewInteractionModule_ProvideRootViewFactory.java:10)
at androidx.test.espresso.base.ViewFinderImpl.getView(ViewFinderImpl.java:62)
at androidx.test.espresso.ViewInteraction$2.call(ViewInteraction.java:276)
at androidx.test.espresso.ViewInteraction$2.call(ViewInteraction.java:268)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

I get this error because in stack has no activity FirstActivity, because my test not start it. So the question is. How I can ISOLATE test only AddTraderActivity?



Solution 1:[1]

Ideally, you should probably use a separate class for testing separate activity.

But, if you need, you can isolate rules per method using following approach

[EDIT] (Caution: You can NOT use @get:Rule annotation anymore):

@Test
public void myTest() {
      // launch desired activity
      var firstActivity: IntentsTestRule<FirstActivity> = IntentsTestRule(FirstActivity::class.java)
      firstActivity.launchActivity(Intent())

      // add tests
      onView(withId(R.id.baseTextInputEditText)).perform(typeText("BASE_TEST"))
      onView(withId(R.id.quoteTextInputEditText)).perform(typeText("QUOTE_TEST"))
}

Solution 2:[2]

This problem can happen if you migrate from ActivityTestRule to ActivityScenarioRule (or ActivityScenario) and you are trying to test an Activity that has the following code in its onCreate() method:

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);

  // Workaround the Android bug of multiple Activity task stacks when
  // the app is launched from the Google Play Store. See:
  // https://issuetracker.google.com/issues/36941942
  // https://stackoverflow.com/questions/4341600/multiple-instances-of-activity-from-google-play-launch
  // https://stackoverflow.com/questions/19545889/app-restarts-rather-than-resumes
  if (!isTaskRoot() &&
      getIntent().hasCategory(Intent.CATEGORY_LAUNCHER) &&
      Intent.ACTION_MAIN.equals(getIntent().getAction())) {
    finish();
    return;
  }

  ...
}

This code worked fine with ActivityTestRule. But it does not work with ActivityScenarioRule or ActivityScenario, because it causes errors when the test tries to launch the Activity:

The problem happens because the test will launch the Activity and then immediately close it in onCreate(). So you must remove the entire if block when using ActivityScenarioRule or ActivityScenario, or add an additional boolean parameter in the if clause, to check if you are running a UI test.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2