【问题标题】:Why is androidx espresso .check() causing androidx.test.espresso.IdlingResourceTimeoutException为什么 androidx espresso .check() 会导致 androidx.test.espresso.IdlingResourceTimeoutException
【发布时间】:2018-11-07 21:20:20
【问题描述】:

我使用 androidx Espresso 进行了一些单元测试,每次运行测试时都会出现以下错误。

androidx.test.espresso.IdlingResourceTimeoutException: Wait for [WorkTrackerIdlingResource] to become idle timed out

为什么我会超时?

它在我的单元测试中的这行代码超时, onView(withId(R.id.map_container)).check(matches(isDisplayed()));

单元测试类:

@RunWith(AndroidJUnit4.class)
@LargeTest
public class CanvassFragmentTest extends TopLevelNavFragmentTest<CanvassFragment> {
    @NonNull
    @Override
    protected TopLevelNavFragment getTargetTopLevelNavFragment(@NonNull MainActivity activity) {
        return activity.mCanvassFragment;
    }

    @Test
    public void mapContainer_isDisplayed() {
        onView(withId(R.id.id1_container)).check(matches(isDisplayed()));
    }


}

还有我们正在尝试测试的具有视图的 xml。

<androidx.coordinatorlayout.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.company.MapContainerFragment">

    <FrameLayout
        android:id="@+id/id1_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </FrameLayout>

   .....
        app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

我已尝试更改 idlepreferences 以使超时为 5 分钟,但我仍然收到错误消息。

编辑 1

根据要求,我添加代码是我在下面这个类的底部添加onTransitionToIdle

public class WaitForWorkRule implements TestRule {

    @Override
    public Statement apply(Statement base, Description description) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                WorkTrackerIdlingResource idler = new WorkTrackerIdlingResource();
                //Espresso.registerIdlingResources(idler);
                IdlingRegistry.getInstance().register(idler);
                try {
                    base.evaluate();
                } finally {
                    IdlingRegistry.getInstance().unregister(idler);
                }
            }
        };
    }

    /**
     * @hide visible for injection
     */
    public static class WorkTrackerIdlingResource implements IdlingResource {

        private static final String TAG = WorkTrackerIdlingResource.class.getSimpleName();

        @Inject
        WorkTracker mWorkTracker;

        @Nullable
        ResourceCallback mResourceCallback;

        public WorkTrackerIdlingResource() {
            getUiTestInjector().inject(this);
        }

        @Override
        public String getName() {
            return TAG;
        }

        @Override
        public boolean isIdleNow() {
            boolean idle = !mWorkTracker.isAnyoneWorking();
            if (idle && mResourceCallback != null) mResourceCallback.onTransitionToIdle();
            return idle;
        }

        @Override
        public void registerIdleTransitionCallback(@Nullable ResourceCallback callback) {
            mResourceCallback = callback;
        }
    }
}

这是我们将其注册为规则的代码。

    @Rule
    public final RuleChain mRuleChain;

    public UiTest(@NonNull Class<T> activityClass) {
    mActivityTestRule = new ActivityTestRule<>(activityClass);
    mRuleChain = createRuleChain();
}



@NonNull
private RuleChain createRuleChain() {
    RuleChain chain = RuleChain.emptyRuleChain()
            .around(new InjectionRule())
            .around(new WaitForWorkRule());

    if (loggedIn()) {
        chain = chain.around(new LoggedInRule());
    }

    return chain.around(mActivityTestRule);
}

【问题讨论】:

  • 看起来您已经在您的MainActivity 中/从您的MainActivity 中注册了一个IdlingResource。您能否发布活动代码或您的注册方式以及您在哪里拨打onTransitionToIdle
  • @Aaron 我已经添加了您要求的代码。
  • 这里简要解释一下为什么你的测试超时:你设置了一个测试规则,在测试开始之前注册一个空闲资源,然后当你的活动开始并且主线程变得忙碌时。通常,当主线程空闲时,测试将继续,但您的空闲资源现在阻塞它并且不调用onTransitionToIdle。我认为您在这里使用空闲资源可能没有用或不正确。你这样做有什么特别的原因吗?
  • @Aaron 老实说,我并没有编写代码的规则部分,而 6 个月前离开的开发人员。我删除了该规则,并编译并运行了测试。当我们迁移到 androidx 时,我在想一些根本性的变化。非常感谢你的帮助!如果你想把你的评论变成一个简短的回答,我很乐意接受。

标签: android unit-testing android-espresso


【解决方案1】:

这里简要解释一下为什么您的测试总是超时:您设置了一个测试规则,在测试开始之前注册一个空闲资源,然后当您的活动开始时,主线程变得忙碌。通常,当主线程空闲时,测试会继续进行,但是您的空闲资源现在会阻塞它并且不会调用 onTransitionToIdle。所以无论你设置多少时间,它总是会超时。

我认为您在这里对空闲资源的使用可能没有用或不正确。如果没有用例,您可以排除该规则,它应该可以正常工作。

【讨论】:

    猜你喜欢
    • 2013-02-25
    • 2012-12-31
    • 2014-01-01
    • 2017-03-10
    • 2019-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多