Обзор фреймворка Ultron для написания UI тестов на Android. Если пишите чисто нативно под Android на Kaspresso, то переход дело вкуса, но вот именно на Compose Multiplatform открывается вся мощь!
🔗 Обсуждение технологии в чате @ultron_framework
8:13 Стандартный фреймворк для UI тестов
16:00 Kaspresso
18:48 Тесты на Ultron
24:28 Сравнение с Google и Kaspresso
25:25 Интеграционные Compose тесты
28:10 Пример 1. Тест на разных ферймворках
40:46 2 интеграционный тест
41:35 useUnmergedTree в Google framework
44:41 Пример 2. Тест на разных ферймворкахю
1:00:56 Ultron, индексы по всему LazyList
1:07:36 Ultron, testTag - 2 способ поиска в LazyList
1:11:41 Allure report, Ultron и Kaspresso
1:23:15 Разница в allure report между ними(Ultron и Kaspresso)
1:31:07 1 тест RecyclerView на других фреймворках, Page Object
1:35:40 Ultron, 1 тест RecyclerView, Page Object
1:39:00 2 тест RecyclerView на других фреймворках, Page Object
1:42:38 Ultron, 2 тест RecyclerView, Page Object
1:53:00 Ultron, Сравнение тестов LazyList и RecyclerView
1:54:11 Ultron, RecyclerView features
2:01:50 Ultron, UI automator, сравнение с Google
2:06:15 Ultron, тест WebView
2:11:04 Ultron listeners (и далее внутрянка)
2:14:43 Ultron extensions
2:19:55 Ultron withAssertion extension
2:23:43 Ultron performOnViewForcibly
2:26:11 Ultron, View custom extensions
2:34:04 Ultron, Compose custom extensions
2:41:16 Ultron, Rules management
2:50:48 Ultron, test data for single test
#compose #тестирование #anroid #ios #desktop
Please open Telegram to view this post
VIEW IN TELEGRAM
YouTube
Ultron - фреймворк для тестирования Android UI и Compose. Демо возможностей
Обзор фреймворка Ultron для написания UI тестов на Android
🔗 Код из видео https://github.com/open-tool/ultron/tree/demo
🔗 Ultron GitHub https://github.com/open-tool/ultron
🔗 Ultron Telegram группа https://xn--r1a.website/ultron_framework
🔗 Каналы "Android Broadcast"…
🔗 Код из видео https://github.com/open-tool/ultron/tree/demo
🔗 Ultron GitHub https://github.com/open-tool/ultron
🔗 Ultron Telegram группа https://xn--r1a.website/ultron_framework
🔗 Каналы "Android Broadcast"…
👍16
Важное изменение в Compose 1.10: pausable composition в lazy prefetch теперь включен по умолчанию. Это фундаментальное улучшение в работе runtime, которое значительно уменьшает лаги при сложных UI-нагрузках.
Раньше композиция, раз начавшись, должна была выполниться до конца. Если она была сложной (много элементов, тяжелые вычисления), это могло заблокировать главный поток дольше, чем длится один кадр и получали Freeze Frame и визуальные лаги скролла.
Теперь Compose Runtime может приостанавливать работу, если время на отрисовку кадра заканчивается, и продолжить её в следующем интервале. Особенно эффективно это работает в связке с предзагрузкой (prefetch) ленивых списков.
🔄 Как это работает с Lazy layouts:
// Увеличиваем окно кэша для большего пространства предзагрузки
val cacheWindow = LazyLayoutCacheWindow(
ahead = 0.5f, // 50% вперед
behind = 0.3f // 30% назад
)
val state = rememberLazyListState(cacheWindow = cacheWindow)
LazyColumn(state = state) {
items(heavyItems) { item ->
HeavyComposable(item) // Теперь не заблокирует UI
}
}
🎯 Ключевые преимущества:
1. Плавная прокрутка — даже с тяжелыми элементами
2. Композиция подстраивается под время для отрисовки кадра — композиция «уступает» место другим операциям
3. Никакой сложной настройки — не требует изменения кода приложения
Эта оптимизация — часть продолжающейся работы Google над производительностью Compose. Уже пробовали? Делитесь наблюдениями в комментариях!
#Compose #Производительность #AndroidDev #JetpackCompose
Please open Telegram to view this post
VIEW IN TELEGRAM
👍44🔥17❤7
🎭 Динамическое управление shared element анимациями в Compose
В Compose 1.10.0 вы можете динамически включать и отключать анимации shared element в зависимости от условий навигации или состояния UI. Это особенно полезно, когда нужно анимировать переход только в определенных сценариях.
Раньше
⚠️ Важно: По умолчанию, если shared element отключается во время анимации, текущая анимация завершается до удаления элемента. Это предотвращает резкие обрывы.
Новая фича даёт разработчикам больше контроля над анимациями, делая интерфейсы более предсказуемыми и оптимизированными.
#Compose #AndroidDev #Анимация #UI
В Compose 1.10.0 вы можете динамически включать и отключать анимации shared element в зависимости от условий навигации или состояния UI. Это особенно полезно, когда нужно анимировать переход только в определенных сценариях.
Раньше
sharedElement() и sharedBounds() автоматически анимировали изменения layout при нахождения совпадению по ключу. Теперь можно контролировать эту анимацию через конфигурацию SharedContentConfig.
// отим анимировать переход только с экрана A на экран B, но не обратно
SharedTransitionLayout {
val transition = updateTransition(currentState)
transition.AnimatedContent { targetState ->
// Конфигурация, зависящая от состояния
fun animationConfig(): SharedTransitionScope.SharedContentConfig {
return object : SharedTransitionScope.SharedContentConfig {
override val SharedTransitionScope.SharedContentState.isEnabled: Boolean
get() = transition.currentState == "A" &&
transition.targetState == "B"
}
}
...
}
}
⚠️ Важно: По умолчанию, если shared element отключается во время анимации, текущая анимация завершается до удаления элемента. Это предотвращает резкие обрывы.
Новая фича даёт разработчикам больше контроля над анимациями, делая интерфейсы более предсказуемыми и оптимизированными.
#Compose #AndroidDev #Анимация #UI
👍9
Compose 1.10 представляет новую функцию
retain, которая заполняет важный пробел между существующими API управления состоянием. Теперь можно сохранять объекты между изменениями конфигурации без необходимости их сериализации!-
remember — сохраняет между рекомпозициями ❌ смена конфигурации-
rememberSavable — сохраняет между пересозданиями активити ⚠️ требует сериализации-
retain — сохраняет при смене конфигурации ✅ без сериализации ❌ не работает при убийстве процесса@Composable
fun MediaPlayer() {
val applicationContext = LocalContext.current.applicationContext
// ExoPlayer будет сохранен при повороте экрана
val exoPlayer = retain {
ExoPlayer.Builder(applicationContext)
.setSeekBackIncrementMs(5000)
.setSeekForwardIncrementMs(5000)
.build()
}
// Воспроизведение не прервется при смене конфигурации
DisposableEffect(Unit) {
onDispose { exoPlayer.release() }
}
// ...
}
Под капотом сохранение объекта происходит через механизм ViewModel и имеет такой же цикл жизни
Фича разработана при активном участии AndroidDev-сообщества, особенно команды Circuit. Отличный пример того, как обратная связь разработчиков влияет на развитие платформы!
#Compose #AndroidDev
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥64👍14❤8👎1