Почему androidx espresso .check () вызывает androidx.test.espresso.IdlingResourceTimeoutException - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть несколько юнит-тестов с использованием 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>

Я попытался изменить настройки ожидания, чтобы время ожидания составляло 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);
}

1 Ответ

0 голосов
/ 08 ноября 2018

Вот краткое объяснение, почему ваш тест всегда истекает: вы устанавливаете правило теста, которое регистрирует ресурс холостого хода до начала теста, затем, когда ваша деятельность начинается, основной поток становится занятым. Как правило, тестирование будет продолжаться, когда основной поток станет бездействующим, но ваш ресурс простоя теперь блокирует его и не вызывает onTransitionToIdle. Поэтому независимо от того, сколько времени вы установили, оно всегда будет превышено.

Я думаю, что использование ресурса холостого хода здесь может быть бесполезным или неправильным. Если для этого нет смысла, вы можете убрать правило, и оно должно работать нормально.

...