Вопрос от подписчика: «Как сделать универсальные стабильные тесты под IOS и Android»
Если коротко, человек тестит гибридное Flutter приложение, тесты на Java через Appium с Flutter Integration Driver
Проблема в том, что на Android можно достучаться до натива и юзать flutterKey и xpath, а на iOS натив толком не работает, только flutterKey, и есть страх, что на реальном устройстве всё сломается
Как я подхожу к задаче единых тестов на обе платформы:
Сначала про корень проблемы
Боль не в самом Flutter, а в том, что локаторы на двух платформах разные
Поэтому различия платформ надо спрятать в одном месте, а не размазывать по всем тестам
1️⃣Фабрика Appium драйвера
Создание драйвера выносим в отдельную фабрику, например AppiumDriverFactory
Она смотрит на окружение, читает платформу из конфига или переменной, и сама собирает нужные capabilities
Тесту прилетает уже готовый драйвер, и вся платформенная грязь остаётся внутри фабрики
2️⃣Кастомные аннотации на локаторы
Дальше самое вкусное, делаем единый Page Object на обе платформы
Создаём свои аннотации, например @AndroidLocator и @iOSLocator, и вешаем их на одно и то же поле элемента
Получается, что элемент описан один раз, но сразу с двумя адресами под каждую ОС
Как это связывается вместе
Нужен небольшой обработчик, который при инициализации Page Object смотрит на текущую платформу
По сути это твоя версия PageFactory, только заточенная под Flutter и две платформы сразу
В итоге в тесте ты просто пишешь loginButton.click(), а под капотом сам подставился нужный локатор
Что делать с разницей возможностей на iOS
Раз на iOS реально живёт в основном flutterKey, строй стратегию вокруг него как основного способа поиска
Это снимает большую часть боли, потому что ключ не зависит от вёрстки и не плывёт между релизами
Про страх с реальным iOS устройством
Симулятор и реальное устройство действительно ведут себя по разному, тут опасения справедливы
Лучше один раз увидеть проблему в CI на ферме устройств, чем поймать её уже в проде
Единые тесты на iOS и Android — это не про общий локатор, а про общий интерфейс и спрятанные различия
Фабрика драйвера прячет настройки платформы, кастомные аннотации прячут разные локаторы, а page object и тест остаются едиными
Опирайся на flutterKey как на самый надёжный якорь и проверяйся на реальных устройствах, тогда гибридный Flutter перестаёт быть для тебя проблемой
Если коротко, человек тестит гибридное Flutter приложение, тесты на Java через Appium с Flutter Integration Driver
Проблема в том, что на Android можно достучаться до натива и юзать flutterKey и xpath, а на iOS натив толком не работает, только flutterKey, и есть страх, что на реальном устройстве всё сломается
Как я подхожу к задаче единых тестов на обе платформы:
Сначала про корень проблемы
Боль не в самом Flutter, а в том, что локаторы на двух платформах разные
Если пытаться писать общий тест и внутри него постоянно писать условия на проверку, мы на iOS или на Android, то код быстро превращается в кашу
Поэтому различия платформ надо спрятать в одном месте, а не размазывать по всем тестам
1️⃣Фабрика Appium драйвера
Создание драйвера выносим в отдельную фабрику, например AppiumDriverFactory
Она смотрит на окружение, читает платформу из конфига или переменной, и сама собирает нужные capabilities
Для Android отдаёт драйвер с одними настройками, для iOS с другими, а тест вообще не знает, на чём он сейчас бежит
Тесту прилетает уже готовый драйвер, и вся платформенная грязь остаётся внутри фабрики
2️⃣Кастомные аннотации на локаторы
Дальше самое вкусное, делаем единый Page Object на обе платформы
Создаём свои аннотации, например @AndroidLocator и @iOSLocator, и вешаем их на одно и то же поле элемента
В Android аннотации кладёшь xpath или нативный локатор, в iOS кладёшь flutterKey
Получается, что элемент описан один раз, но сразу с двумя адресами под каждую ОС
Как это связывается вместе
Нужен небольшой обработчик, который при инициализации Page Object смотрит на текущую платформу
Он читает аннотации поля, берёт локатор именно для активной ОС и подставляет его в элемент
По сути это твоя версия PageFactory, только заточенная под Flutter и две платформы сразу
В итоге в тесте ты просто пишешь loginButton.click(), а под капотом сам подставился нужный локатор
Что делать с разницей возможностей на iOS
Раз на iOS реально живёт в основном flutterKey, строй стратегию вокруг него как основного способа поиска
Договорись с разработчиками, чтобы ключевые элементы получали стабильные flutterKey прямо в коде приложения
Это снимает большую часть боли, потому что ключ не зависит от вёрстки и не плывёт между релизами
Про страх с реальным iOS устройством
Симулятор и реальное устройство действительно ведут себя по разному, тут опасения справедливы
Поэтому критичный прогон обязательно гоняй хотя бы иногда на реальном девайсе, а не только на симуляторе
Лучше один раз увидеть проблему в CI на ферме устройств, чем поймать её уже в проде
Единые тесты на iOS и Android — это не про общий локатор, а про общий интерфейс и спрятанные различия
Фабрика драйвера прячет настройки платформы, кастомные аннотации прячут разные локаторы, а page object и тест остаются едиными
Опирайся на flutterKey как на самый надёжный якорь и проверяйся на реальных устройствах, тогда гибридный Flutter перестаёт быть для тебя проблемой