如何使断言等待 IdlingResource 断言

how to make assert to wait for IdlingResource to assert

我想使用空闲资源,因为我在我的应用程序中使用 RxJava 和 EventBus,有时我的测试会失败(我认为那是因为同步)。

依赖关系:

androidTestCompile 'com.android.support.test:runner:0.4'
androidTestCompile 'com.android.support.test:rules:0.4'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
androidTestCompile 'com.android.support.test.espresso:espresso-intents:2.2.1'
androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.2.1') {
    exclude group: 'com.android.support', module: 'appcompat'
    exclude group: 'com.android.support', module: 'support-v4'
    exclude module: 'recyclerview-v7'
}
androidTestCompile 'junit:junit:4.12'
androidTestCompile 'com.squareup.retrofit:retrofit-mock:1.9.0'
androidTestCompile 'com.squareup.assertj:assertj-android:1.1.0'
androidTestCompile 'com.squareup.spoon:spoon-client:1.2.0'

测试失败:

@RunWith(AndroidJUnit4.class)
@SmallTest
public class PushNotificationTests {

    @Test
    public void testSomething(){

        // do things...
        MyIdlingResource eventBusIdlingResource = new MyIdlingResource();
        registerIdlingResources(eventBusIdlingResource);

        Order.Status status = Order.getCurrentObservable().toBlocking().first().getStatus();
        assertThat(status).isEqualTo(Order.Status.PROGRESS);   // Fail,

        unregisterIdlingResources(eventBusIdlingResource)
    }

}

尝试但不成功:

@RunWith(AndroidJUnit4.class)
@SmallTest
public class PushNotificationTests {

    @Test
    public void testSomething(){

        // do things...

        MyIdlingResource eventBusIdlingResource = new MyIdlingResource();
        registerIdlingResources(eventBusIdlingResource);

        // Wait manually?
        int sleeps = 0;
        while(!eventBusIdlingResource.isIdleNow() || sleeps < 10){
            sleep(100);
            sleeps++;
        }

        Order.Status status = Order.getCurrentObservable().toBlocking().first().getStatus();
        assertThat(status).isEqualTo(Order.Status.PROGRESS);   // Fail,

        unregisterIdlingResources(eventBusIdlingResource)
    }

}

最终将 sleep 方法封装在 class.

import android.support.test.espresso.IdlingResource;

/**
 * Have functions to sleep the processor because assertions are not linked to
 * {@link IdlingResource} to do assertions, so should be used before asserts if there's an
 * idle process.
 */
public class IdlingResourceSleeper {

    private static final int SLEEPS_LIMIT = 50;
    private static final int SLEEPS_TIME = 10;

    /**
     * Used to sleep {@link IdlingResourceSleeper#SLEEPS_LIMIT} times and
     * {@link IdlingResourceSleeper#SLEEPS_TIME} ms until idlingResource.isIdleNow() is false.
     *
     * @param idlingResource
     */
    public static void sleep(IdlingResource idlingResource) {
        int sleeps = 0;
        while (!idlingResource.isIdleNow() || sleeps < SLEEPS_LIMIT) {
            android.os.SystemClock.sleep(SLEEPS_TIME);
            sleeps++;
        }

    }
}

来源: - gist - post

在检查 UI 的状态之前,我有同样的要求强制 Espresso 闲置。对我有用的是添加一个始终为真的视图断言,因为 Espresso 在执行之前等待空闲状态。

onView(isRoot()).check(matches(anything()));

我知道这是一个老问题,但我在搜索时 运行 遇到了这个问题,并认为其他人也可能如此。此行为现​​在内置于 Espresso.onIdle().

void onIdle ()

Loops the main thread until the app goes idle.

Only call this method for tests that do not interact with any UI elements, but require Espresso's main thread synchronisation! This method is mainly useful for test utilities and frameworks that are build on top of Espresso.

For UI tests use onView(Matcher) or onData(Matcher). These Apis already use Espresso's internal synchronisation mechanisms and do not require a call to onIdle().

https://developer.android.com/reference/android/support/test/espresso/Espresso#onidle