Основные сложности при автоматизации тестирования мобильных приложений:
Однако, в автоматизации моб приложений мы используем тот же паттерн Page Objects, Selenium под капотом и тот же подход к написанию тестов (Arrange(подготавливаем данные) - Act(выполняем действие) - Assert(проверяем)).
Appium | Espresso | XCUITest | Detox | Selendroid | |
---|---|---|---|---|---|
iOS | + | - | + | + | + |
Android | + | + | - | + | + |
Type | Balck box | White box | Black box | Grey box | Black box |
Programming Lang | Almost any | Kotlin | Swift | JavaScript | Java |
Cost | Free | Free | Free | Free | Free |
Community | Very active | Apple | Wix | Average | |
Speed | Slow | Fast | Fast | Fast | Slow |
Web, native, hybrid | + | Hybrid and native | Only native | Only | + |
Selendroid - достаточно старый инструмент, используется скорее теми компаниями которые взяли его еще давно, неизвестно поддерживается ли он на текущий день.
Detox - подходит только для приложений на react native, нативные моб приложения им не получится автоматизировать.
Espresso, XCUITest - нативные инструменты, заточные под свою платформу.
Appium - это http сервер.
У нас есть тестовый скрипт, мы передаем его в Appium и Appium транслирует его на мобильные устройства, с помощью json wire protocol.
Appium - это обертка над теми же нативными инструментами(XCUITest и UIAutomator, Expresso), т.к. он все свои команды дальше ретранслирует в команды понятные нативным инструментам.
Для iOS используется XCUITest, для Android можно выбрать между UIAutomator и Expresso.
Для Expresso добавили поддержку примерно в 2020 г, он на 20% быстрее, чем UIAutomator. Плюс Expresso делает Appium немного Grey box'ом, потому что есть возможность сделать backdoor к приложению и в целом делает немного более открытым код приложения.
JSONWP(JSON wire protocol) - механизм, созданный командой разработчиков WebDriver. Этот протокол представляет собой набор четко определенных стандартизированных endpoints, открытых через RESTfull API.
AppiumDriver.getPageSource();
- этот метод вызовет HTTP-запрос, и получит ответ от API. Назад вернется page source в формате строки.
/session/:sessionId/source
- эндпоинт, который обрабатывает метод getPageSource.
Appium работает с Android через Espresso и UIAutomator. Поддерживается Google. Espresso быстрее чем UIAutomator.
Несколько лет назад под капотом использовался не XCUITests, а другой фреймворк. Но Apple решила прекратить его поддержку и выпустила XCUITests. А XCUITests на тот момент противоречил философии Appium, в том что нам не нужно модифицировать код, т.к. XCUITests нужно было собирать вместе с приложением.
И некоторое время, Appium нельзя было использовать для iOS приложений. На помощь пришел Facebook и сделал WebDriverAgent Server. При запуске тестов на Appium'e на моб устройство также ставится WebDriverAgent и он транслирует команды от Appium к XCUITests.
Это самый надежный вариант. Но построить свою ферму дорого и сложно поддерживать, тк устройства всегда были подключены к сети и нужно выполнять настройки, чтобы не всплывали всяки popup сообщения и если они всегда в сети, то нужно будет часто менять батарейку и собрать парк из разных девайсов будет дорого и сложно.
Оптимальный вариант. Не так много кейсов, которые репродьюсятся только на реальных устройствах. Они есть но их не много.
для iOS - используются симуляторы, на Android поднимаются эмуляторы.
Используются стандартные эмуляторы, которые предоставляет Android Studio и симуляторы от XCode для iOS.
Самые удобные, тк просто указываем url на хост в ферме и запускаем. Но это очень дорого, плюс вопрос к секьюрности для запусков тестов.
При запуске на реальном устройстве: 1. собираем .ipa файл, подписанный сертификатом организации 2. берем девайс, добавленный в провижен организации 3. используется аккаунт с сертификатом разработчика
При запуске на симуляторе просто собираем через XCode .app файл. На симуляторе нельзя установить файл с расширением .ipa, потому что там другая архитектура и он там не запустится.
Собираем apk через Gradle и Android Studio на эмулятор и на реальное устройство и можно работать.
https://qa-automation.git-doc.evo.dev/mobile/ubuntu.html
Можно искать элементы по id и по xPath:
resource-id = id
@AndroidFindBy(id = "tvProSalePay")
@AndroidFindBy(xpath = "//android.widget.TextView[@text = 'XL']")
Можно использовать только Appium Inspector, так как нет других инструментов для этой цели.
Можно искать по id, iOSClassChain, iOS predicate string (в порядке снижения скорости).
По xPath тоже можно но крайне не рекомендуется так как это происходит очень медленно из за того что в iOS приложениях нет xml дерева и appium его вычисляет самостоятельно а на это тратится время.
@iOSXCUITFindBy(id="client name")
@iOSXCUITFindBy(iOSClassChain="**/XCUIElementTypeButton[`name == 'icRatingStar'`]")
Свой тип локаторов.
String selector = "type == 'XCUIElementTypeButton' AND value BEGINSWITH[c] 'bla' AND visible == 1"
Некоторые объекты не имеют выделенного элемента в DOM дереве и сложно с ними взаимодействовать отдельно, например взять текст. Встречается в сообщениях об ошибке, тост сообщениями, поп-апами.
Решение:
Когда мы делаем скриншот в Appium, мы видим дерево только тех элементов, которые есть сейчас на экране, то что вне мы не видим.
Решение:
Дойти до элементов вне зоны видимости мы можем только проскролив.
HashMap<String, String> scrollObject = new HashMap<>();
scrollObject.put("element", element.getId());
scrollObject.put("toVisible", "true");
driver.executeScript("mobile:scroll", scrollObject);
protected void scrollToElementAndroid(String scrollableListId, String selectionText){
((AndroidDriver) driver).findElementByAndroidUIAutomator("new UiScrollable(new UiSelector().scrollable(true)"
+ ".resourceId(\"" + scrollableListId + "\"))"
+ ".setAsHorizontalList().scrollIntoView(new UiSelector().text(\"" + selectionText + "\"))").click();
}
Универсальный скролл
public void swipeUpToFindElement(By by, int maxSwipes){
int alreadySwiped = 0;
while(driver.findElements(by).size() == 0){
if (alreadySwiped > maxSwipes){
waitForElementToBePresent(by, "Невозможно найти элемент по свайпу", Constants.SMALL_TIMEOUT);
return;
}
swipeUpQuick();
Log.info("Выполнен свайп");
++alreadySwiped;
}
}
У Android и iOS есть свои особенности.
Разные атрибуты у элементов iOS - value, android - text iOs - visible, android - displayed iOS - enabled, android - checked, checkable, enabled
Различия в основных флоу приложения на Android и на iOS
Часто при работе с веб вью на разных версиях Android у элементов разный xPath
@AndroidFindAll(
)
watch?v=zp0qC6JT0rE