Android UIAutomator: Как дождаться выполнения любого из нескольких условий?

Вопрос или проблема

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

По сути, я хочу дождаться появления любого из возможных тегов. Как только первый появится, код должен вернуть true. Я не знаю, как это сделать. Вот что я делаю в данный момент:

fun MacrobenchmarkScope.waitForDashboardContent() {
    device.wait(Until.hasObject(By.res("dashboard_feed")), 10_000)
    val lazyColumn = device.findObject(By.res("dashboard_feed"))
    lazyColumn.wait(Until.hasObject(By.res("dashboard_section_title")), 2_000)
}

ChatGPT предложил что-то, что было бы отлично, если бы этот метод существовал:

lazyColumn.wait(Until.hasObject(By.any(By.res("dashboard_section_title"),By.res("another_section_title"))),2_000)

Когда я указал ему, что By.any не существует, он дал мне это предложение:

val lazyColumn = device.findObject(By.res("dashboard_feed"))
val startTime = System.currentTimeMillis()
val timeout = 2000

while (System.currentTimeMillis() - startTime < timeout) {
    if (lazyColumn.hasObject(By.res("dashboard_section_title")) ||
        lazyColumn.hasObject(By.res("another_section_title"))) {
        // Один из элементов был найден в пределах таймаута
        break
    }
    // Небольшая задержка, чтобы предотвратить слишком частые циклы
    Thread.sleep(100)
}

Есть ли лучшее решение?

Ответ или решение

Как ждать выполнения нескольких условий в Android UIAutomator

Создание политик базового профиля для вашего приложения часто требует ожидания динамически генерируемого контента, такого как лента новостей. Эта задача может стать сложной, особенно когда точный тег, по которому вы хотите произвести поиск, может отсутствовать или изменяться. Для этой цели идеально подходит библиотека UIAutomator, которая предоставляет мощные инструменты для автоматизации тестирования пользовательского интерфейса на Android.

Проблема

Вы хотите реализовать метод, который будет ждать появления одного из нескольких возможных элементов пользовательского интерфейса. В вашем первоначальном коде вы используете метод device.wait, однако он поддерживает ожидание только одного условия. На текущий момент решение, предложенное ChatGPT, представляет собой цикл с ожиданием, которое, хотя и работает, может быть улучшено с точки зрения производительности и удобочитаемости.

Код

Для более эффективного ожидания появления одного из нескольких условий, мы можем использовать более обобщённый подход с использованием методов UIAutomator. Давайте разберем вашу задачу с использованием оптимизированного примера кода:

fun MacrobenchmarkScope.waitForAnyCondition() {
    val possibleConditions = listOf(
        By.res("dashboard_section_title"),
        By.res("another_section_title")
    )

    val startTime = System.currentTimeMillis()
    val timeout = 2000 // Зададим таймаут 2 секунды

    while (System.currentTimeMillis() - startTime < timeout) {
        for (condition in possibleConditions) {
            if (device.hasObject(condition)) {
                // Как только один из элементов найден, возвращаем true
                return
            }
        }
        // Задержка для предотвращения слишком частого опроса
        Thread.sleep(100)
    }
    // Если ни один из элементов не найден в указанный таймаут, можно вернуть false
}

Объяснение

  1. Создание списка условий: Мы создаем список элементов, которые ожидаем, используя listOf(). Это позволяет легко добавлять или изменять условия в будущем.

  2. Цикл ожидания: Мы реализуем цикл, который будет работать в течение заданного таймаута. Каждую итерацию мы проверяем наличие любого из элементов из списка.

  3. Проверка наличия элементов: Метод device.hasObject(condition) используется для проверки существования каждого элемента. Как только один из элементов присутствует, функция завершится.

  4. Задержка между итерациями: Мы используем Thread.sleep(100) для предотвращения слишком частого опроса состояния пользовательского интерфейса, что позволяет снизить нагрузку на процессор и улучшить производительность.

  5. Обработка таймаута: Если время ожидания превышает заданный таймаут, функция возвращает значение по умолчанию, которое можно настроить по вашему усмотрению (например, возвращать false).

Заключение

Данный подход не только делает ваш код более читабельным и структурированным, но и позволяет избежать излишне запутанного логического контроля. Используя элементы управления, предоставляемые UIAutomator, вы сможете более эффективно ждать выполнения любых условий. Этот метод поможет вам повысить стабильность тестирования вашего приложения и быстрее адаптироваться к изменяющемуся контенту на экране.

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

Оцените материал
Добавить комментарий

Капча загружается...