有什么方法可以知道 activity 是否已使用 Espresso 启动?

Is there any way to know if an activity has been started with Espresso?

我正在使用 Espresso 进行 Activity 转换测试,但我不知道这是否是最好的方法:

public void testStartLogin() {
    onView(withId(R.id.register)).perform(click());
    onView(withId(R.id.login_password)).check(matches(isDisplayed()));
    onView(withId(R.id.login_show_password)).check(matches(isDisplayed()));
}

最后两个来自第二个 activity 但这对我来说看起来很糟糕。有什么不同的方法吗?

Espresso 作者不鼓励访问实际 activity 以确定应用程序的状态。

就像真正的用户不知道他们面前的 activity 是什么一样,他们通过查看屏幕上的元素来确定他们在应用程序中的位置。我不认为您当前的方法看起来很糟糕。

但是,espresso 附带 ActivityLifecycleMonitor 来跟踪活动状态。您可以像这样访问它并执行断言:

final Activity[] activity = new Activity[1];

InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
        @Override
        public void run() {
           activity[0] =Iterables.getOnlyElement(ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(Stage.RESUMED));
}

assertTrue(activity instanceof MyActivity.class);

这看起来并不比您的方法好,而且如果您之前的 activity 在单击注册按钮后正在做任何工作,它也可能不稳定并且受竞争条件的影响。

在我看来,针对属于某个 activity 的视图断言某些内容是检查该特定 activity 是否已启动的一种非常优雅的方法。来自官方文档:

At the same time, the framework prevents direct access to activities and views of the application because holding on to these objects and operating on them off the UI thread is a major source of test flakiness. Thus, you will not see methods like getView and getCurrentActivity in the Espresso API.

但是,有一种方法可以完成您的需要,如图所示 here。在我的版本中,我还定义了一个断言方法,如:

 public void assertCurrentActivityIsInstanceOf(Class<? extends Activity> activityClass) {
    Activity currentActivity = getActivityInstance();
    checkNotNull(currentActivity);
    checkNotNull(activityClass);
    assertTrue(currentActivity.getClass().isAssignableFrom(activityClass));
}

我在测试方法中使用的。

对于我自己的测试,我在使用它时没有任何问题(Espresso 2.0!),但它有点多余,因为我仍然会检查属于那个 activity 的视图。所以它有效,但我不推荐它。

祝你好运!

编辑

还有可能检查意图是否从第一个 activity 发送到第二个(检查 this short tutorial),但这并不一定意味着第二个 activity 正确显示其所有视图。您仍然应该检查它们是否显示,这会让您回到开始的地方。

你可以这样做:

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

response from @riwnodennyk

抢劫

这个简短的片段应该有效:

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