Эспрессо и postDelayed
У меня есть действие, которое использует вызов postDelayed:
public class SplashActivity extends Activity {
private Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(...);
handler.postDelayed(new Runnable() {
public void run() { finish(); }
}, 3000L);
}
}
Это работает при запуске приложения, и мне нужно перемещаться по нему и экрану входа в систему. Однако loopMainThreadUntilIdle UIController, похоже, не принимает во внимание лежащее в основе MessageQueue в обработчике. Таким образом, это действие завершается немедленно, пока в очереди еще есть сообщения.
onView(withId(R.id.splash_screen)).perform(new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return isAssignableFrom(View.class);
}
@Override
public String getDescription() {
return "";
}
@Override
public void perform(final UiController uiController, final View view) {
uiController.loopMainThreadUntilIdle();
}
});
Я не могу понять, как блокировать, пока очередь не будет опустошена. Сам андроид мне мешает от выполнения многих вещей, которые я бы попытался (например, расширение обработчика и переопределение метода postDelayed и т. д...)
У кого-нибудь есть предложения о том, как обращаться с postDelayed?
Я бы предпочел избегать uiController.loopMainThreadForAtLeast, который кажется хаки (как нить.спать хотел)
1 ответ:
Когда Эспрессо ждет, он действительно принимает во внимание
MessageQueue
, но по-другому, чем вы думаете. Чтобы бытьпраздным , очередь должна быть либо пустой, , либо есть задачи, которые будут выполняться в течение более чем 15 миллисекунд с этого момента .Вы можете проверить код самостоятельно, особенно метод
loopUntil()
вUiControllerImpl.java
и файлQueueInterrogator.java
. В последнем файле вы также найдете логику того, как Espresso проверяетMessageQueue
(методdetermineQueueState()
).Теперь, как решить ваш проблема? есть много способов:
Используйте
AsyncTask
вместоHandler
, спящий в фоновом потоке и выполняющий действияonPostExecute()
. Это делает трюк, потому что эспрессо будет ждать окончанияAsyncTask
, но вам может не понравиться накладные расходы другого потока.Спите в своем тестовом коде, но вам уже не нравится этот подход.
Напишите свой обычай
IdlingResource
: это общий механизм, позволяющий Эспрессо знать, когда что-то бездействует, чтобы он может запускать действия и утверждения. Для этого подхода вы могли бы:
Используйте класс
CountingIdlingResource
, который поставляется с эспрессоВызовите
increment()
, когда вы разместите свой runnable иdecrement()
внутри runnable после запуска вашей логикиЗарегистрируйте свой
IdlingResource
в тестовой установке и отмените его регистрацию в разрывеСм. также: docs and sample, другой пример