Espresso的一個關鍵功能是測試程序和被測應用是同步執(zhí)行的。這是基于idling的概念:Espresso等待app處于idle狀態(tài),才會執(zhí)行下個動作和檢查下個斷言。
Idle
app處于idle狀態(tài)是什么意思?Espresso檢查下面幾個場景:
- 在當前消息隊列中沒有UI事件;
- 在默認的AsyncTask線程池沒有任務;
但是,如果app以其他方式執(zhí)行長時間運行操作,Espresso不知道如何判斷這些操作已經完成。如果是這樣的話,可以通過編寫自定義的IdelingResource來通知Espresso的等待時間。
IntentServiceIdlingResource
假設你使用IntentService來做一些長時間運算,然后通過broadcast將結果返回給activity。我們希望Espresso一直等到結果返回,才來驗證界面顯示正確。
為了實現(xiàn)IdlingResource,需要重寫3個函數:getName(),registerIdleTransitionCallback(),isIdleNow()。
@Override
public String getName() {
return IntentServiceIdlingResource.class.getName();
}
@Override
public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
this.resourceCallback = resourceCallback;
}
@Override
public boolean isIdleNow() {
boolean idle = !isIntentServiceRunning();
if (idle && resourceCallback != null) {
resourceCallback.onTransitionToIdle();
}
return idle;
}
private boolean isIntentServiceRunning() {
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo info : manager.getRunningServices(Integer.MAX_VALUE)) {
if (RepeatService.class.getName().equals(info.service.getClassName())) {
return true;
}
}
return false;
}
idle邏輯是在isIdleNow()實現(xiàn)的。在這個例子中,我們通過查詢ActivityManager來檢查IntentService是否正在運行。如果IntentService停止運行,我們調用resourceCallback.onTransitionToIdle()來通知Espresso。
注冊idling resource
為了讓Espresso等待自定義的idling resource,你需要注冊它。在測試代碼的@Before方法中執(zhí)行注冊,在@After中執(zhí)行注銷。
@Before
public void registerIntentServiceIdlingResource() {
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
idlingResource = new IntentServiceIdlingResource(instrumentation.getTargetContext());
Espresso.registerIdlingResources(idlingResource);
}
@After
public void unregisterIntentServiceIdlingResource() {
Espresso.unregisterIdlingResources(idlingResource);
}
完整示例
Check out完整示例的源碼。嘗試注釋掉IdlingResource注冊,測試會失敗。