Espresso - How can I check if an activity is launched after performing a certain action?

AndroidAndroid ActivityAndroid Espresso

Android Problem Overview


the following is one of my Espresso test cases.

    public void testLoginAttempt() {
        Espresso.onView(ViewMatchers.withId(R.id.username)).perform(ViewActions.clearText()).perform(ViewActions.typeText("[email protected]"));
        Espresso.onView(ViewMatchers.withId(R.id.username)).perform(ViewActions.clearText()).perform(ViewActions.typeText("invalidpassword"));

        Espresso.onView(ViewMatchers.withId(R.id.login_button)).perform(ViewActions.click());
        // AFTER CLICKING THE BUTTON, A NEW ACTIVITY WILL POP UP.
        // Clicking launches a new activity that shows the text entered above. You don't need to do
        // anything special to handle the activity transitions. Espresso takes care of waiting for the
        // new activity to be resumed and its view hierarchy to be laid out.
        Espresso.onView(ViewMatchers.withId(R.id.action_logout))
                .check(ViewAssertions.matches(not(ViewMatchers.isDisplayed())));

    }

Currently what I did was to check if a view in the new activity (R.id.action_logout) is visibible or not. If visible, I will assume tha the activity opened successfully. But it doesn't seem to work as I expected. Is there a better way to check if a new activity is successfully launched instead of checking a view in that activity is visible? Thanks

Android Solutions


Solution 1 - Android

You can use:

intended(hasComponent(YourExpectedActivity.class.getName()));

Requires this gradle entry:

androidTestCompile ("com.android.support.test.espresso:espresso-intents:$espressoVersion")

The import for the intended() and hasComponent()

import static android.support.test.espresso.intent.Intents.intended;
import static android.support.test.espresso.intent.matcher.IntentMatchers.hasComponent;

as mentioned by Shubam Gupta please remember to call Intents.init() before calling intended(). You can eventually call it in the @Before method.

Solution 2 - Android

Try:

intended(hasComponent(YourActivity.class.getName()));

Also, keep in mind

java.lang.NullPointerException is thrown if Intents.init() is not called before intended()

Solution 3 - Android

You may do it as follows:

    @Test
public void testLoginAttempt() {
    Espresso.onView(ViewMatchers.withId(R.id.username)).perform(ViewActions.clearText()).perform(ViewActions.typeText("[email protected]"));
    Espresso.onView(ViewMatchers.withId(R.id.username)).perform(ViewActions.clearText()).perform(ViewActions.typeText("invalidpassword"));

    Intents.init();
    Espresso.onView(ViewMatchers.withId(R.id.login_button)).perform(ViewActions.click());
    Intents.release();
}

java.lang.NullPointerException is thrown if Intents.init() is not called.

Solution 4 - Android

Make sure the Espresso intent library is in the gradle dependencies

androidTestImplementation "com.android.support.test.espresso:espresso-intents:3.0.1"

Then import these two in your test file

import static android.support.test.espresso.intent.Intents.intended
import static android.support.test.espresso.intent.matcher.IntentMatchers.hasComponent

Then add IntentsTestRule in your test class

@Rule
@JvmField
val mainActivityRule = IntentsTestRule(MainActivity::class.java)

Finally check the activity has launched intent

@Test
fun launchActivityTest() {
    onView(ViewMatchers.withId(R.id.nav_wonderful_activity))
            .perform(click())

    intended(hasComponent(WonderfulActivity::class.java!!.getName()))
}

Solution 5 - Android

The problem is that your application performs the network operation after you click login button. Espresso doesn't handle (wait) network calls to finish by default. You have to implement your custom IdlingResource which will block the Espresso from proceeding with tests until IdlingResource returns back in Idle state, which means that network request is finished. Take a look at Espresso samples page - https://google.github.io/android-testing-support-library/samples/index.html

Solution 6 - Android

Try with

intended(hasComponent(new ComponentName(getTargetContext(), ExpectedActivity.class)));

Look at response from @riwnodennyk

Solution 7 - Android

I use this approach:

// The IntentsTestRule class initializes Espresso Intents before each test, terminates the host activity, and releases Espresso Intents after each test
    @get:Rule
    var tradersActivity: IntentsTestRule<TradersActivity> = IntentsTestRule(TradersActivity::class.java)
    @get:Rule
    var jsonViewActivity: IntentsTestRule<JsonViewActivity> = IntentsTestRule(JsonViewActivity::class.java)

    @Test
    fun scrollToItemAndClick() {
     onView(withId(R.id.tradersRecyclerView)).perform(RecyclerViewActions.actionOnItemAtPosition<RecyclerView.ViewHolder>(ITEM_POS, click()))

        // check is activity was started
        intended(hasComponent(JsonViewActivity::class.java.getName()))
    }

Solution 8 - Android

@RunWith(RobolectricTestRunner.class)
public class WelcomeActivityTest {

    @Test
    public void clickingLogin_shouldStartLoginActivity() {
        WelcomeActivity activity = Robolectric.setupActivity(WelcomeActivity.class);
        activity.findViewById(R.id.login).performClick();

        Intent expectedIntent = new Intent(activity, LoginActivity.class);
        assertThat(shadowOf(activity).getNextStartedActivity()).isEqualTo(expectedIntent);
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser2062024View Question on Stackoverflow
Solution 1 - AndroidbaskaraView Answer on Stackoverflow
Solution 2 - AndroidShubham GuptaView Answer on Stackoverflow
Solution 3 - AndroidAbdul WadoodView Answer on Stackoverflow
Solution 4 - Androids-hunterView Answer on Stackoverflow
Solution 5 - AndroiddenysView Answer on Stackoverflow
Solution 6 - AndroidlujopView Answer on Stackoverflow
Solution 7 - AndroidAlexeiView Answer on Stackoverflow
Solution 8 - AndroidFAHAD HAMMAD ALOTAIBIView Answer on Stackoverflow