Android Macrobenchmark 1.2.4: StartupMode.COLD превосходит тесты. Внутри блока измерения UiAutomator не может найти ни одного объекта

Я уже давно добавил модуль макротестирования с метриками StartupTimingMetric и FrameTimingMetric, и моя настройка работала нормально. С тех пор я не проводил тесты по некоторым причинам. Недавно у меня было время вернуться и обновить потоки пользователей и снова запустить тесты. Но мои FrameTimingMetric тесты начали давать сбои на этапе бега measureBlock. UiAutomator не смог найти ни одного объекта по идентификатору ресурса внутри measureBlock, но смог увидеть их все в setupBlock. Я использую Compose, и необходимые составные элементы testTag добавлены.

Год назад, когда я изначально добавил тесты, все работало нормально, но теперь они перестали. В конце концов мне удалось решить проблему, удалив startupMode = StartupMode.COLD. Я понятия не имею, почему этот флаг влияет на видимость составных элементов только в measureBlock, тогда как setupBlock работает нормально.

Может ли кто-нибудь помочь мне понять, почему это происходит?

// NOT working case

        rule.measureRepeated(
            packageName = InstrumentationRegistry.getArguments().getString("targetAppId")
                ?: throw Exception("targetAppId not passed as instrumentation runner arg"),
            metrics = listOf(FrameTimingMetric()),
            compilationMode = compilationMode,
            startupMode = StartupMode.COLD,
            iterations = 10,
            setupBlock = {
                pressHome()
                startActivityAndWait()
                // other setup methods
                // "MyList" is visible here and list var is NOT null
                // val list = device.findObject(By.res("MyList"))
            },
            measureBlock = {
                // "MyList" is NOT visible here and list var IS null
                val list = device.findObject(By.res("MyList"))
            }
        )
// Working case

        rule.measureRepeated(
            packageName = InstrumentationRegistry.getArguments().getString("targetAppId")
                ?: throw Exception("targetAppId not passed as instrumentation runner arg"),
            metrics = listOf(FrameTimingMetric()),
            compilationMode = compilationMode,
            // startupMode = StartupMode.COLD,      // <- REMOVE this line
            iterations = 10,
            setupBlock = {
                pressHome()
                startActivityAndWait()
                // other setup methods
                // "MyList" is visible here and list var is NOT null
                // val list = device.findObject(By.res("MyList"))
            },
            measureBlock = {
                // "MyList" is visible here and list var is NOT null
                val list = device.findObject(By.res("MyList"))
            }
        )
0
0
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если используется StartupMode.COLD, процесс приложения завершается между выполнение setupBlock и measureBlock, чтобы подготовить приложение не запуская процесс.

Если вам нужно, чтобы процесс оставался активным, используйте StartupMode.WARM, который перезапускает действия без перезапуска процесса, или установите startupMode на null и вызовите killProcess() внутри setupBlock.

Вы можете подписаться на b/278214396, чтобы получать больше новостей об этом в будущем.

Спасибо @mlykotom за помощь. Очень приятно получить ответ от тебя, человека, за чьими видео и лабораторными работами я следил, чтобы узнать о макробенчмарке. StartupMode.WARM действительно получилось

Marat 14.06.2024 10:43

Честно говоря, удивительно видеть изменение в поведении FrameTimeMetrics + StartupMode.COLD. Видео «Проверка производительности — навыки MAD» по-прежнему показывают, что StartupMode.COLD можно использовать с FrameTimeMetrics. Посмотрев видео с безумными навыками и пройдя кодовую лабораторию, у меня сложилось впечатление, что процесс приложения один и тот же от начала итерации до конца. Таким образом, setupBlock и Measure Block являются частью одного процесса. Они нужны только для того, чтобы разделить, что измерять, а что пропускать при измерениях.

Marat 14.06.2024 13:10

Поэтому кажется неинтуитивным, что startMode.COLD будет контролировать состояние процесса между блоками setup и measure. Ожидаемым поведением FrameTimeMetrics + StartupMode.COLD будет полное завершение процесса и холодный запуск приложения между итерациями. Тот факт, что UIAutomator не видит никаких элементов пользовательского интерфейса в блоке мер, кажется ошибкой, а не ожидаемым поведением.

Marat 14.06.2024 13:27
startupMode на null и вызов killProcess() в setupBlock — это конфигурация шкафа, которая вернет поведение, описанное в видео о навыках MAD и лаборатории кода. Итак, спасибо за подсказку и за открытие Issuetracker.google.com/issues/278214396. Я не могу не согласиться с поднятыми вами вопросами относительно текущего поведения библиотеки.
Marat 14.06.2024 13:31

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

Marat 14.06.2024 13:32

Поведение, скорее всего, останется прежним, так что при ХОЛОДНОМ запуске будет возможность каким-то образом подготовить процесс приложения, что в противном случае было бы невозможно, потому что когда вы каким-либо образом взаимодействуете с процессом (например, отправляете широковещательную рассылку), Процесс пробуждается и, следовательно, не будет ХОЛОДНЫМ. Возможно, API для режимов запуска немного изменится, но об этом пока говорить рано, поэтому я бы рекомендовал использовать текущий подход :)

mlykotom 17.06.2024 16:30

Другие вопросы по теме