Можно ли отключить всплывающие уведомления или подождать, пока всплывающие уведомления исчезнут во время тестирования

Я тестирую приложение с Espresso. У меня есть один вопрос, можно ли дождаться, пока не будут показаны тосты. В моем приложении есть много разных всплывающих уведомлений, но во время тестирования у меня возникают проблемы с ними, потому что, насколько я могу предположить, фокус уходит на всплывающее уведомление, и я получаю совершенно другую иерархию представлений, как я вижу в журналах ошибок.
Итак, мой вопрос: можно ли скрыть все (для всей системы с корневым доступом) или просто подождать, пока на экране не появятся всплывающие уведомления, или, может быть, можно вручную установить фокус на иерархию представления активности.
Я бы был благодарен за любую помощь в решении этой проблемы.
Спасибо.

P.S. Отключение всплывающих уведомлений непосредственно где-то в моем приложении не вариант, потому что это добавляет дополнительную логику в приложение, которое требуется только во время тестирования.


person CROSP    schedule 13.08.2015    source источник
comment
Ваш P.S меня порадовал, так держать. Что касается вопроса, предлагает ли Espresso какой-либо тип предложений waitForCondition, чтобы вы могли легко установить тайм-аут для исчезновения тостов?   -  person JohanShogun    schedule 14.08.2015
comment
Thread.sleep отлично работает только для одного тоста, AFAIK LONG time составляет 3,5 секунды, но что делать, если последовательно отображаются несколько тостов, и это занимает гораздо больше времени, было бы здорово, если бы был какой-либо способ вернуть фокус на активность   -  person CROSP    schedule 14.08.2015
comment
Если вы сделаете что-то вроде этого stackoverflow.com/questions/21417954/espresso-thread-sleep у вас может быть более длительный тайм-аут, который не обязательно будет занимать все время.   -  person JohanShogun    schedule 14.08.2015
comment
Я бы посмотрел на этот ответ: stackoverflow.com/a/33387980/654026   -  person David Santiago Turiño    schedule 11.10.2016


Ответы (2)


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

Здесь я использую CountingIdlingResource, который представляет собой бездействующий ресурс, управляющий счетчиком: когда счетчик изменяется с ненулевого на ноль, он уведомляет об обратном вызове перехода.

Вот полный пример; ключевые моменты следуют:

public final class ToastManager {
    private static final CountingIdlingResource idlingResource = new CountingIdlingResource("toast");
    private static final View.OnAttachStateChangeListener listener = new View.OnAttachStateChangeListener() {
        @Override
        public void onViewAttachedToWindow(final View v) {
            idlingResource.increment();
        }

        @Override
        public void onViewDetachedFromWindow(final View v) {
            idlingResource.decrement();
        }
    };

    private ToastManager() { }

    public static Toast makeText(final Context context, final CharSequence text, final int duration) {
        Toast t = Toast.makeText(context, text, duration);
        t.getView().addOnAttachStateChangeListener(listener);
        return t;
    }

    // For testing
    public static IdlingResource getIdlingResource() {
        return idlingResource;
    }
}

Как показать тост:

ToastManager.makeText(this, "Third", Toast.LENGTH_SHORT).show();

Как настроить/снять тест:

@Before
public void setUp() throws Exception {
    super.setUp();
    injectInstrumentation(InstrumentationRegistry.getInstrumentation());
    Espresso.registerIdlingResources(ToastManager.getIdlingResource());
    getActivity();
}

@After
public void tearDown() throws Exception {
    super.tearDown();
    Espresso.unregisterIdlingResources(ToastManager.getIdlingResource());
}
person Gil Vegliach    schedule 15.08.2015

Я не нашел идеального решения для этого, но лучше всего сделать переменную-член mToast видимой для тестирования и использовать ее для отмены любого активного всплывающего уведомления в @After, например:

При отображении всплывающего уведомления (производственный код для тестируемого действия):

@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
Toast mToast;

private void showToast(final String text) {
    mToast = Toast.makeText(this, text, Toast.LENGTH_LONG);
    mToast.show();
}

Тестовый код (в том же пакете, что и тестируемый код):

    @After
    public void tearDown() {
        // Remove any toast message that is still shown:
        Toast toast = mActivityRule.getActivity().mToast;
        if (toast != null) {
            toast.cancel();
        }
    }

Это потребует от вас небольшого изменения производственного кода, но использование @VisibleForTesting в последней версии Android Studio приведет к ошибке, если вы используете переменную-член в другом месте.

person Eirik W    schedule 06.06.2017