Подтвердить что ты не робот

Правильный способ использования IdlingResource в Espresso Android

Я пишу тесты UI с помощью Espresso. Приложение тесно сотрудничает с сервером, поэтому во многих случаях мне нужно дождаться, когда будет вычисляться либо значение, либо данные будут получены и отображены, и т.д. Espresso предлагает использовать IdlingResource для этого. Мои классы IdlingResource выглядят так (простой и понятный пример).

public class IRViewVisible implements IdlingResource {

private View view;
private ResourceCallback callback;

public IRViewVisible(View view) {
    this.view = view;
}

@Override
public String getName() {
    return IRViewVisible.class.getName();
}

@Override
public boolean isIdleNow() {
    if(view.getVisibility() == View.VISIBLE && callback != null) {
        callback.onTransitionToIdle();
        return true;
    }
    return false;
}

@Override
public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
    this.callback = resourceCallback;
}
}

Пожалуйста, поправьте меня, если я ошибаюсь где угодно (иногда мне кажется, что мои IdlingResources работают неправильно). Я регистрирую ресурс холостого хода в setUp() следующим образом:

IRViewVisible ir = new IRViewVisible(View v);
Espresso.registerIdlingResources(ir).

Отмените регистрацию на tearDown().

Я нашел эту статью (есть раздел "Зарегистрировать компонент, связанный с экземпляром Activity" ) - я не использую его схему, но я проверил hashcode который был установлен в IdlingResource после регистрации (в каждом методе), и это не тот же вид - все хэши разные.

Другой вопрос: один тестовый класс (это результат) не может влиять на другой тестовый класс, не так ли?

4b9b3361

Ответ 1

Я предполагаю, что ваша проблема связана с getName(), возвращая одно и то же имя для всех экземпляров IRViewVisible. Это означает, что вы можете иметь только один зарегистрированный экземпляр за раз - любые последующие регистрации будут терпеть неудачу (беззвучно!).

Вы упомянули, что вы очищаете IdlingResources в конце каждого теста, но если вы регистрируете сразу несколько экземпляров, вам нужно убедиться, что каждый экземпляр имеет уникальное имя. это не ясно из вашего вопроса, если вы регистрируете несколько экземпляров IRViewVisible в одном тесте.

Что касается вашего последнего вопроса: Да, это возможно. Android не полностью закрывает приложение между тестовыми запусками - просто Activity. Общие вещи, которые могут вызвать проблемы:

  • Не удалось удалить постоянное состояние (сохраненные данные).
  • Не удалось очистить глобальное состояние - например, статические переменные/синглеты
  • Не дожидаться завершения фоновых потоков.

В стороне, стоит отметить, что вы вызываете только onTransitionToIdle() внутри isIdleNow(). Это работает (спасибо @Be_Negative для головок!), Но это может сильно замедлить ваши тесты, так как Espresso будет проводить только опрос isIdleNow() каждые несколько секунд. Если вы вызываете onTransitionToIdle(), как только вид становится видимым, он должен значительно ускорить процесс.

Мне нужно что-то похожее на ваш IRViewVisible, здесь мои усилия.

Ответ 2

Итак, метод isIdleNow() никогда не вернет true, если вы не установите обратный вызов idlingResource? Я считаю, что лучше реорганизовать его так:

@Override
public boolean isIdleNow() {
    boolean idle = view.getVisibility() == View.VISIBLE;
    if(idle && callback != null) {
        callback.onTransitionToIdle();
    }
    return idle;
} 

Ответ 3

Ну, в первую очередь вам не нужно использовать Espresso IdlingResource для проверки вызовов сервера. Если вы используете AsyncTask в своих вызовах на сервере, Espresso сможет узнать, когда простаивать, а когда нет. Если этого недостаточно: попробуйте реорганизовать свой код следующим образом:

  IRViewVisible idlingResource = new IRViewVisible(yourView);
  IdlingPolicies.setMasterPolicyTimeout(waitingTime * 2, TimeUnit.MILLISECONDS);
        IdlingPolicies.setIdlingResourceTimeout(waitingTime * 2, TimeUnit.MILLISECONDS);

        // Now we wait
        Espresso.registerIdlingResources(idlingResource);

        // Stop and verify


        // Clean up
        Espresso.unregisterIdlingResources(idlingResource);

Надеюсь быть полезным.