Зависит от ситуации. Для чисто Compose-экранов может быть достаточно. Т.к. мы мигрируем с View - нам удобно поправить в E2E тестах только те экраны, которые переписаны на Compose. И для этого подходит AndroidComposeTestRule (чтобы получить PageObject от Activity, а не передавая Composable функцию в тест напрямую). Похожим образом работает Kakao и Kaspresso
Примерно так же, как и экраны на View. Добавляется AndroidComposeTestRule + делается PageObject на основе SemanticsNodeInteractionsProvider. У нас свой тестовый фреймворк, в котором коллеги это поддержали.
Фрагменты с Compose нужны для более поэтапной миграции. Даже сейчас большие приложения - это далеко не single activity. У нас есть множество как Activity, так и фрагментов. Одновременно переезжать и по вью-стеку и по стеку навигации может быть неподъёмно.
Модуль принимает на вход Dependencies и выставляет свой контракт в виде API.
Если в его API два или более классов (хотя лучше использовать в API только интерфейсы) можно использовать композицию, например:
interface SomeFeatureApi : BaseAPI {
fun firstInteractor(): FirstInteractor
fun secondInteractor(): SecondInteractor
}
Если же используем интерфейсы, то можно просто отнаследовать FeatureApi от них, например:
Мы пока делаем для каждого фиче-модуля отдельный Dagger-модуль в app. Разделение AppComponent у нас в планах после вынесения всех фиче-модулей из монолита.
Очень зависит от конкретной проблемы.
Можно для начала попробовать отключить анимации при прогоне теста.
Если это не поможет, можно использовать функцию KautomatorWaitForIdleSettings.boost() при конфигурации Kaspresso. Она отключает waitForIdleTimeout, который не дает совершить действие теста. А механизм flakySafely повторит действие, если оно не удалось в первый раз. Подробнее можно почитать тут.
Совсем необязательно связывать модули через один AppComponent. В примере так сделано только потому, что там всего три маленьких фиче-модуля.
При масштабировании, если фичи достаточно хорошо изолируются по зависимостям, их склейку можно разбивать по разным Dagger-компонентам внутри app-модуля.
Улучшения, по сравнению с подходом Евгения, были связаны больше с решением выявленных архитектурных недостатков и появившимися возможностями Kotlin. Как мне кажется, производительность будет больше зависеть от конкретной реализации и используемого DI-фреймворка.
Этот подход полностью совместим с предыдущим, поэтому переходить можно постепенно при добавлении новых модулей.
Привет. Расскажу про навыки Android-разработчиков, которые делают пользовательские продукты.
Мы следим за развитием индустрии. У нас используются как новейшие библиотеки из Jetpack, Coroutines, так и проверенные временем Clean Architecture, RxJava2, Moxy и многое другое. Весь новый код пишем на Kotlin. Конкретный стек зависит от проекта. Мы всегда за "обновление", если это помогает нам в работе (подробнее о выборе библиотек отвечал выше).
Мы также активно смотрим за новинками в библиотеках и подходах Android-разработки, такими как Compose и многомодульность.
Разработчикам так же полезно разбираться в базовом уровне в C++ и JNI для обертки используемых нативных библиотек.
Более подробно про такую вакансию можно посмотреть тут.
Если не получается через Espresso, можно попробовать с помощью UI Automator. В Kaspresso есть обертка над ним (Kautomator), которая содержит функцию device.uiDevice.swipe(startX, startY, endX, endY, steps).
FlakySafely работает посредством перехвата эксепшнов, возникающих при определенном действии над View. Поэтому его нужно обернуть в flakySafely{}. Если нужно просто ожидание, то в крайних случаях можно использовать какую-нибудь реализацию wait() (например, Thread.sleep()).
Любые вопросы про Kaspresso можно также задавать в чатике.
3) Уязвимости в используемых библиотеках, а также возможность их использования в соотвествии с лицензионным соглашением проверяются отдельными командами Лаборатории.
Первоначальное решение о необходимости затянуть библиотеку принимают разработчики. Если это достаточно узко специализированная библиотека, на которую не завязывается весь проект – тут всё просто.
На вашем примере перехода с RxJava2 на Coroutines расскажу про процедуру принятия решения.
Инициатор внедрения должен детально изучить новую библиотеку. После чего он предлагает команде рассмотреть плюсы от такого перехода и возможные проблемы. Если решение о внедрении принимается – мы стараемся подтянуть уровень знаний всей команды о ней. А инициатор становится неким "евангелистом", которому уходят наиболее сложные кейсы. Только после этого происходит переход.
В новом проекте без RxJava2 мы можем сразу начать использовать Coroutines.
Можно посмотреть пример в Kakao
У нас сделано похоже, относительно нашей тестовой инфры. В опенсорс не успели только вынести.
Готового публичного примера нет. А в чем видите проблему?
Зависит от ситуации. Для чисто Compose-экранов может быть достаточно.
Т.к. мы мигрируем с View - нам удобно поправить в E2E тестах только те экраны, которые переписаны на Compose. И для этого подходит
AndroidComposeTestRule
(чтобы получить PageObject от Activity, а не передавая Composable функцию в тест напрямую).Похожим образом работает Kakao и Kaspresso
Примерно так же, как и экраны на View.
Добавляется
AndroidComposeTestRule
+ делается PageObject на основеSemanticsNodeInteractionsProvider
.У нас свой тестовый фреймворк, в котором коллеги это поддержали.
Если не трогать "контейнеры" - activity/fragment - навигация не меняется, пока мы явно не захотим её упростить.
У NavComponent Compose примерно так же, как и раньше https://developer.android.com/jetpack/compose/navigation#deeplinks
И кастомизация тем и расширения очень зависят от конкретного приложения и необходимости. Но в целом никаких сложностей там возникнуть не должно.
Фрагменты с Compose нужны для более поэтапной миграции. Даже сейчас большие приложения - это далеко не single activity. У нас есть множество как Activity, так и фрагментов.
Одновременно переезжать и по вью-стеку и по стеку навигации может быть неподъёмно.
Можно во вторую часть добавить еще Kaspresso https://kasperskylab.github.io/Kaspresso/Wiki/Screenshot_tests/
Модуль принимает на вход
Dependencies
и выставляет свой контракт в видеAPI
.Если в его
API
два или более классов (хотя лучше использовать вAPI
только интерфейсы) можно использовать композицию, например:Если же используем интерфейсы, то можно просто отнаследовать FeatureApi от них, например:
Это интерфейс-маркер. Такой же, как, например,
Serializable
. Он способствует читаемости кода.Сейчас около 27 модулей, из них 18 feature-модуля.
Мы пока делаем для каждого фиче-модуля отдельный Dagger-модуль в app. Разделение AppComponent у нас в планах после вынесения всех фиче-модулей из монолита.
Очень зависит от конкретной проблемы.
Можно для начала попробовать отключить анимации при прогоне теста.
Если это не поможет, можно использовать функцию
KautomatorWaitForIdleSettings.boost()
при конфигурации Kaspresso. Она отключаетwaitForIdleTimeout
, который не дает совершить действие теста. А механизмflakySafely
повторит действие, если оно не удалось в первый раз. Подробнее можно почитать тут.Добрый день.
Можно посмотреть документацию в репозитории. Для старта может быть полезным также почитать Wiki. Там же есть ссылки на обзорные видео.
Совсем необязательно связывать модули через один AppComponent. В примере так сделано только потому, что там всего три маленьких фиче-модуля.
При масштабировании, если фичи достаточно хорошо изолируются по зависимостям, их склейку можно разбивать по разным Dagger-компонентам внутри app-модуля.
Спасибо за ссылку. На первый взгляд подходы достаточно похожи.
Посмотрю внимательнее, возможно, применим у себя.
Улучшения, по сравнению с подходом Евгения, были связаны больше с решением выявленных архитектурных недостатков и появившимися возможностями Kotlin. Как мне кажется, производительность будет больше зависеть от конкретной реализации и используемого DI-фреймворка.
Этот подход полностью совместим с предыдущим, поэтому переходить можно постепенно при добавлении новых модулей.
Привет. Расскажу про навыки Android-разработчиков, которые делают пользовательские продукты.
Мы следим за развитием индустрии. У нас используются как новейшие библиотеки из Jetpack, Coroutines, так и проверенные временем Clean Architecture, RxJava2, Moxy и многое другое. Весь новый код пишем на Kotlin. Конкретный стек зависит от проекта. Мы всегда за "обновление", если это помогает нам в работе (подробнее о выборе библиотек отвечал выше).
Мы также активно смотрим за новинками в библиотеках и подходах Android-разработки, такими как Compose и многомодульность.
Разработчикам так же полезно разбираться в базовом уровне в C++ и JNI для обертки используемых нативных библиотек.
Более подробно про такую вакансию можно посмотреть тут.
device.uiDevice.swipe(startX, startY, endX, endY, steps)
.flakySafely{}
. Если нужно просто ожидание, то в крайних случаях можно использовать какую-нибудь реализациюwait()
(например,Thread.sleep()
).Любые вопросы про Kaspresso можно также задавать в чатике.
3) Уязвимости в используемых библиотеках, а также возможность их использования в соотвествии с лицензионным соглашением проверяются отдельными командами Лаборатории.
Первоначальное решение о необходимости затянуть библиотеку принимают разработчики. Если это достаточно узко специализированная библиотека, на которую не завязывается весь проект – тут всё просто.
На вашем примере перехода с RxJava2 на Coroutines расскажу про процедуру принятия решения.
Инициатор внедрения должен детально изучить новую библиотеку. После чего он предлагает команде рассмотреть плюсы от такого перехода и возможные проблемы. Если решение о внедрении принимается – мы стараемся подтянуть уровень знаний всей команды о ней. А инициатор становится неким "евангелистом", которому уходят наиболее сложные кейсы. Только после этого происходит переход.
В новом проекте без RxJava2 мы можем сразу начать использовать Coroutines.