为什么在Android API 22上的Espresso测试中,IdlingResource为null?

问题描述 投票:1回答:2

编辑:我已经在Android API 22上的两个设备上测试了下面的一个,在API 19上测试了一个,API 19上的一个没有问题。任何想法版本之间可能有什么区别?

我正在为我的Android设置espresso测试,其中IdlingResource与示例here相同。

我的测试设置:

@Rule
public ActivityTestRule<MainActivity> mMainActivity =
        new ActivityTestRule(MainActivity.class);

private IdlingResource mIdlingResource;

@Before
public void registerIdlingResource() {
    mIdlingResource = mMainActivity.getActivity().getIdlingResource();
    IdlingRegistry.getInstance().register(mIdlingResource);
}

在我的Activity中每次更改Idle状态时,我都会调用:

if (mIdlingResource != null) {
    mIdlingResource.setIdleState(false);
} else {
    Log.d("error ", "idle resource is null");
}

当我尝试更改活动中的空闲状态时,我的问题出现了 - 在创建活动和IdlingResource可用之间似乎存在延迟。

在序列的第一次测试中,IdlingResource永远不可用 - 因此我不能将IdlingResource的initialValue设置为false,然后再切换回true。这似乎是由this article中描述的注释生命周期引起的:

enter image description here

据我所知,Activity由@Rule创建,然后IdlingResource在@Before中实例化。由于Activity已在运行,因此我尝试更改状态的每个点的空闲资源都为空。

在后续测试中,只跳过setIdleState的第一个实例(发生在onCreate中) - 可能与@Rule的Activity生命周期有关? - 但其他人按预期运作。

在第一次测试之前,是否有最佳做法让@Rule和@Before按顺序工作?

java android junit android-espresso
2个回答
1
投票

您可以在活动中使用static IdlingResource。在开始后台任务之前初始化mIdlingResource(因为你已经编写了它,所以我不包括初始化代码)。

private static IdlingResource mIdlingResource;

//Getter for mIdlingResource
public IdlingResource getmIdlingResource() {
    return mIdlingResource;
}

然后,您可以从测试中访问此静态资源,而不是创建新变量。

@Before
public void registerIdlingResource() {
    IdlingRegistry.getInstance().register(mMainActivity.getActivity().getmIdlingResource());
}

然后mIdlingResource在活动中不会为空。

注意 - Google建议使用CountingIdlingResource。你可以在这里找到实现 - https://developer.android.com/reference/android/support/test/espresso/idling/CountingIdlingResource

更新:检查注释中的代码后。

当你在注册时第一次调用它时,你的IdlingResource就会被创建。

只需在getIdlingResource()中调用onCreate()一次(或者在你打电话给setIdleState之前)。保留其余代码相同。它不会创建重复项,因为在初始化之前执行null检查。


1
投票

在IdlingResource可用之前,此活动启动问题的最佳解决方案是设置规则,以便它不会启动活动。此方法的好处是您不必在Activity中手动注册IdlingResource。

要实现此解决方案,请使用以下ActivityTestRule构造函数

ActivityTestRule(Class<T> activityClass, boolean initialTouchMode, boolean launchActivity)

所以代码看起来像:

@Rule
public ActivityTestRule<MainActivity> mMainActivity =
        new ActivityTestRule(MainActivity.class, false, true);

private IdlingResource mIdlingResource;

@Before
public void registerIdlingResource() {
    mIdlingResource = mMainActivity.getActivity().getIdlingResource();
    IdlingRegistry.getInstance().register(mIdlingResource);
    mMainActivity.launchActivity(new Intent());
}
© www.soinside.com 2019 - 2024. All rights reserved.