4

Я запускаю тесты Espresso в своем приложении для Android. Тест чешуйчатый. Он может надежно утверждать, что модель данных обновлена. Моя проблема в том, что ViewMatchers не могут совпадать с одним и тем же значением в представлении, потому что ViewDataBinding еще не обновил Views. (По крайней мере, большую часть времени проходит тест.)Как заставить Espresso ждать, пока Data Binding обновит представление с помощью модели данных?

Есть ли такая вещь, как IdlingResource, которая перестает работать, когда ViewDataBinding не имеет ожидающих изменений в представлении?

Моя работа вокруг представляет собой сочетание вызова executePendingBindings() и небольшой Thread.sleep (...)

+0

'executePendingBindings' должно быть достаточно: связывание будет выполняться сразу при вызове этого метода, а не во время следующего кадра' Choreographer' – pskink

+0

Это была моя первоначальная мысль. Но, оказывается, тестовые прогоны в потоке AndroidJUnit и executePendingBindings должны выполняться на MainThread. Планирование его на Main не является быстрым или достаточно блокирующим для неудачного утверждения в потоке AndroidJUnit. – Rene

+0

Вы нашли решение? У меня есть аналогичная проблема, когда во время эспрессо-тестов неверные значения передаются в привязку данных, но если я добавлю точку останова и дождаюсь момента, она отправит правильные значения, представления будут правильно привязаны, а эспрессо найдет вид –

ответ

1

В докладе ошибка упоминается с помощью отражения для изменения ViewDataBinding.USE_CHOREOGRAPHER к false для испытаний, так вот решение, которое я придумал:

public static void setFinalStatic(Field field, Object newValue) throws Exception { 
    field.setAccessible(true); 

    Field modifiersField; 
    try { 
     modifiersField = Field.class.getDeclaredField("accessFlags"); 
    } catch(NoSuchFieldException e) { 
     //This is an emulator JVM ¯\_(ツ)_/¯ 
     modifiersField = Field.class.getDeclaredField("modifiers"); 
    } 
    modifiersField.setAccessible(true); 
    modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); 

    field.set(null, newValue); 
} 

Затем просто определить ActivityTestRule для деятельности при испытании, и переопределить его beforeActivityLaunched(). Это необходимо сделать до начала действия (в отличие от аннотации @Before), поскольку ViewDataBinding инициализирует Looper, если он не использует CHOREOGRAPHER.

@Override 
protected void beforeActivityLaunched() { 
    super.beforeActivityLaunched(); 
    //Because we are using data-binding, we avoid using CHOREOGRAPHER 
    try { 
     ReflectionUtils.setFinalStatic(
      ViewDataBinding.class.getDeclaredField("USE_CHOREOGRAPHER"), false); 
    } catch (Exception e) { 
     Assert.fail(e.getMessage()); 
    } 
} 

Таким образом, вы можете избавиться от этого Thread.sleep()

+0

Не работает для меня. Это не работает с NoSuchFieldException для «accessFlags». Но я вижу accessFlags для класса Field для Android. Не знаю, почему это терпит неудачу для меня. Я запустил его на эмулятор леденцов. – rpattabi

+0

@rpattabi Вы можете попробовать «модификаторы» перед «accessFlags», как описано [здесь] (https://code.google.com/p/android/issues/detail?id=220247#c4). Дай мне знать, если это работает. Я должен был заметить, что это решение работает при использовании реального устройства, поэтому было бы ошибкой при выполнении тестов внутри эмулятора jvm. – verybadalloc

+0

Я написал информацию, которую вы указали в ссылке: -) «модификаторы» для рабочего стола jvm и «accessFlags» для android jvm. Ни один из них не работает для меня. – rpattabi

 Смежные вопросы

  • Нет связанных вопросов^_^