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

依然范特西╮ 提交于 2019-12-17 15:32:37

问题


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("nonexistinguser@krossover.com"));
        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


回答1:


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.




回答2:


Try:

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

Also, keep in mind

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




回答3:


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()))
}



回答4:


Try with

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

Look at response from @riwnodennyk




回答5:


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




回答6:


You may do it as follows:

    @Test
public void testLoginAttempt() {
    Espresso.onView(ViewMatchers.withId(R.id.username)).perform(ViewActions.clearText()).perform(ViewActions.typeText("nonexistinguser@example.com"));
    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.




回答7:


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()))
    }



回答8:


@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);
    }
}


来源:https://stackoverflow.com/questions/25998659/espresso-how-can-i-check-if-an-activity-is-launched-after-performing-a-certain

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!