Android Espresso - 如何在执行特定操作后检查活动是否启动?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25998659/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 09:55:34  来源:igfitidea点击:

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

androidandroid-activityandroid-espresso

提问by user2062024

the following is one of my Espresso test cases.

以下是我的 Espresso 测试案例之一。

    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

目前我所做的是检查新活动(R.id.action_logout)中的视图是否可见。如果可见,我将假设该活动已成功打开。但它似乎并没有像我预期的那样工作。有没有更好的方法来检查新活动是否成功启动,而不是检查该活动中的视图是否可见?谢谢

回答by baskara

You can use:

您可以使用:

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

Requires this gradle entry:

需要此 gradle 条目:

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

The import for the intended()and hasComponent()

对于进口intended()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 @Beforemethod.

正如 Shubam Gupta 提到的,请记得在打电话Intents.init()之前先打电话intended()。您最终可以在@Before方法中调用它。

回答by Shubham Gupta

Try:

尝试:

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

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

Also, keep in mind

另外,请记住

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

java.lang.NullPointerException如果Intents.init()之前没有被调用,则抛出intended()

回答by denys

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

问题是您的应用程序在您单击登录按钮后执行网络操作。默认情况下,Espresso 不处理(等待)网络调用完成。您必须实现您的自定义 IdlingResource,这将阻止 Espresso 继续进行测试,直到 IdlingResource 返回空闲状态,这意味着网络请求已完成。看看 Espresso 示例页面 - https://google.github.io/android-testing-support-library/samples/index.html

回答by Abdul Wadood

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.NullPointerExceptionis thrown if Intents.init()is not called.

java.lang.NullPointerException如果Intents.init()未调用则抛出。

回答by s-hunter

Make sure the Espressointent library is in the gradle dependencies

确保Espresso意图库位于 gradle 依赖项中

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 IntentsTestRulein your test class

然后在你的测试类中添加IntentsTestRule

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

回答by lujop

Try with

试试

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

Look at response from @riwnodennyk

看看@riwnodennyk 的回复

回答by a_subscriber

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

回答by FAHAD HAMMAD ALOTAIBI

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