Espresso тест на ожидание

387
21 января 2017, 10:59

Есть следующий тест, который при переходе в форму логина, вводит некорректные данные, в ответ на которые ему выводится дилоговое окно с текстом "Warning":

@Test
fun signInUserWithInvalidPassword() {
    goToSignIn()
    AcceptanceHelper.updateValidationTextView(R.string.ui_data_attribute_email, VALID_EMAIL)
    AcceptanceHelper.updateValidationTextView(R.string.ui_data_attribute_password, "987654321")
    AcceptanceHelper.clickOnButtonInLayout(R.id.mainSignButton, R.string.common_signin_button_text, R.id.inputLayout)
    onView(isRoot()).perform(AcceptanceHelper.waitId(R.id.titleTextView, 5000))
    AcceptanceHelper.checkTextView(R.id.titleTextView, "Warning")

Проблема в том что тест падает на строчке:

        onView(isRoot()).perform(AcceptanceHelper.waitId(R.id.titleTextView, 5000))

Мол открывается во фрагменте диалог, элементы которого он не находит. А вот и собственно сам метод waitId:

fun waitId(id: Int, millis: Long): ViewAction {
    return object : ViewAction {
        override fun getConstraints(): Matcher<View> {
            return isRoot()
        }
        override fun getDescription(): String {
            return "wait for a specific view with id <$id> during $millis millis."
        }
        override fun perform(uiController: UiController, view: View) {
            uiController.loopMainThreadUntilIdle()
            val startTime = System.currentTimeMillis()
            val endTime = startTime + millis
            val viewMatcher = withId(id)
            do {
                for (child in TreeIterables.breadthFirstViewTraversal(view)) {
                    // found view with required ID
                    if (viewMatcher.matches(child)) {
                        return
                    }
                }
                uiController.loopMainThreadForAtLeast(50)
            } while (System.currentTimeMillis() < endTime)
            // timeout happens
            throw PerformException.Builder()
                    .withActionDescription(this.description)
                    .withViewDescription(HumanReadables.describe(view))
                    .withCause(TimeoutException())
                    .build()
        }
    }
}

Возможно кто то сталкивался, и может подсказать.

Answer 1

Как вариант можете воспользоваться вместо вашего метода следующим способом:

SystemClock.sleep(5000)

или

Thread.sleep(1500);

Также можно упростить Ваш метод и проставлять значения таймаута заранее:

 fun waitFor(id: Int, millis: Long): ViewAction {
    return object : ViewAction {
        override fun getConstraints(): Matcher<View> {
            return isRoot()
        }
        override fun getDescription(): String {
            return "Wait for a specific view with $id during $millis millis."
        }
        override fun perform(uiController: UiController, view: View) {
            uiController.loopMainThreadUntilIdle()
        }
    }
}

Но не стоит забывать, что это не самые лучшие варианты, так как Вам придётся постоянно ожидать n-ое кол-во времени. Лучше всего загружать нужные Вам элементы, в данном случае текст, который вы хотите проверить сразу, как только загрузился диалог. Поэтому попробуйте еще такой вариант как IdlingResource, а в качестве примера попробуйте разобраться перейдя по ссылке здесь.

READ ALSO
Тест не проходит

Тест не проходит

Есть вспомогательный класс DialogIdlingResource, благодаря которому пытаюсь запустить свои тесты, все тесты проходят за исключением этого запускается...

300
Создание библиотеки. Не могу понять, как предоставить возможность ее использовать

Создание библиотеки. Не могу понять, как предоставить возможность ее использовать

ЗдравствуйтеНаписал библиотеку с анимациями, своими классами, методами и т

398
Undefined step при запуске тестов на русском

Undefined step при запуске тестов на русском

Пытаюсь писать тесты на русском в cucumber javaЕсть

428
Google карта не реагирует на android &gt; 5

Google карта не реагирует на android > 5

Использую Google карты в своем приложении и при компиляции на android 44

325