python

Облачные платформы для мобильного тестирования

  • четверг, 22 августа 2019 г. в 00:21:38
https://habr.com/ru/post/464433/
  • Тестирование IT-систем
  • Python
  • Разработка мобильных приложений
  • Тестирование веб-сервисов
  • Тестирование мобильных приложений


И вот настало то время, когда нашим нуждам тестирования стало тесно на рабочем столе тестировщика. Душа попросилась в облака. На самом деле нет. Не совсем.



Наши цели и задачи


(спешащий читатель, можешь мотать до следующего раздела)


Мы занимаемся разработкой финансового приложения для иностранного рынка, которое доступно в разных форматах: для десктоп-браузеров (веб-сайт и расширение для Google Chrome), для мобильных браузеров, а так же в виде гибридного приложения для телефонов. В связи со спецификой приложения, мы особое внимание уделяем тестированию приложения на различных конфигурациях и устройствах. Для нас важна стабильная и безопасная работа приложения как на настольных браузерах наших клиентов, так и на их любых устройствах.


Причиной поиска облачной фермы устройств для тестирования для нас стала смена формата работы с офисного на полностью удалённый и распределённый (между городами и странами). То есть, если раньше для тестирования мы могли раньше собрать разные устройства в кучу (в буквальном смысле) и протестировать в ручном режиме за одним столом очередную сборку, то сейчас это стало сделать попросту невозможно. Более того, с ростом функционала, для уменьшения ручной работы, регрессионные наборы важных тестов мы автоматизируем, а значит, после сборки нам нужно иметь возможность позвать тесты на желаемой конфигурации и устройстве, причём лучше это сделать сразу же, как только сборка раскатится на staging.


При этом самым простым и очевидным решением является использование эмуляторов для Android и симуляторов для iOS устройств в нашем DevOps конвеере. Однако, что сравнительно легко реализуется на рабочем компьютере разработчика, для использования в облаке становится сложной и дорогой задачей. Для быстрой работы того же эмулятора Android требуется x86 сервер с поддержкой HAXVM, а для симулятора iOS — только MacOS устройство с xcode. Но, к сожалению, даже решив такую задачу остаётся вопрос с разрывом между поведением программного обеспечения на эмуляторах и реальных устройствах. Например каждый второй релиз мы ловим странные баги на Samsung устройствах, которые не воспроизводятся на эмуляторах. Ну, и, конечно редкие экзотические «китайцы» «радуют» уникальным и багами, которые тоже хотелось бы ловить ещё на этапе разработки.


В результате у нас появилось понимание необходимости использования облачной фермы мобильных устройств, на которых мы могли бы быстро прогонять свои тесты и при необходимости производить отладку в ручном режиме. И к которой был бы доступ у всей нашей команды из любой точки мира (мы любим работать даже в путешествиях).



Наши тесты написаны на Python 3.7 (далее это будет важно), как стек мы используем tox + pytest + Selenium + Appium, ну и небольшой набор полезных питонячих библиотек. Мы обязательно тестируем машины на Windows и MacOS с браузерами Edge, Firefox, Chrome, Safari, а так же устройства на Android и iOS — с браузерами и приложением. Тестов у нас на каждое устройство не сильно много (меньше тысячи), но при тестировании в один поток на устройствах полный набор выполняется пару часов. Поэтому критерием выбора сервиса для нас будет:


  • Тестирование через API (Selenium/Appium)
  • Устройства iOS, Android
  • Поддержка мобильного браузер-тестирования
  • Поддержка загрузки и тестирования приложений
  • Наличие референсного устройства (GooglePixel (Android 9) и iPhone X (iOS 12+))
  • Ручная отладка
  • Логирование (плюс скриншоты, запись видео прогона)
  • Парк устройств и их доступность
  • Среднее время выполнения теста
  • Цена

Желательно, но не обязательно:


  • Поддержка python на уровне сервиса (что бы это ни значило)
  • Поддержка десктопных устройств \ браузеров

Результаты исследования рынка


За неделю я пошерстил интернет и попробовал с десяток разных сервисов. Большинство из них предоставляет бесплатное время для тестирования возможностей. Результаты моего исследования, тем более выводы носят субъективный характер. Ваше мнение и результаты могут отличатся от моего.


На Хабре я нашёл статью за 2017 год посвящённую этой же теме, но с тех пор появились и новые сервисы, да и наша задача чуть строже. Так, например, «вкусные» сервисы вроде Samsung Remote Test Lab, Firebase Test Lab, Xamarin Test Cloud нам, увы, не подходят.


Вне игры


Samsung Remote Test Lab



Ссылка.


Сервис бесплатно предоставляет возможность попробовать поработать с различными устройствами Samsung, в том числе с самыми новыми, включая телевизоры или умные часы на Tizen (ограничение — максимум 10 часов в день, за день сервис бесплатно выдаёт 10 кредитов, что равно 2,5 часам в день, минимальная сессия — полчаса (2 кредита)). Это очень неплохо для отладки и поиска корневых причин возникновения ошибок на определённых устройствах, сервис даже предоставляет доступ к удалённой отладке (remote debug bridge, доступ к консоли и системным логам), но, к сожалению, сервис не предоставляет API-доступ к устройствам. Единственная возможность «автоматизировать» — это записать пользовательские действия и затем их воспроизвести в местном средстве автоматизации.


Firebase Test Lab



Ссылка.


Сервис от Google позволяет бесплатно (не совсем) протестировать своё приложение на устройствах под управлением Android и iOS. Но есть один нюанс — сервис требует использования либо нативных средств автоматизации (UIAtomator2 и Espresso для Android и XCTest для iOS), либо с помощью автоматических пауков (crawler) для Android — Robo Test и Game Loop Test. То есть использовать UIAutomator и Selenium увы, не выйдет. Что же касается бесплатности — бесплатный пакет ограничен 10 тестами на эмуляторах и пятью на реальных устройствах в день. Если нужно больше, то за каждый дополнительный час придётся заплатить еще $1 и $5 соответственно. В целом для наших задач это было бы неплохим выбором, если бы мы писали тесты с нуля, но перерабатывать несколько сотен тестов уже совсем не хочется — это попросту дорого. Да и получается, что нам пришлось бы сильно разойтись в тестах между десктоп-версиями и мобильными, что сильно усложнит поддержку.


Visual Studio App Center



Ссылка.


Бывший Xamarin Test Cloud. Этот сервис наконец-то поддерживает Appium и позволяет проводить тестирование на тысяче разных устройств. Но, как и в случае с другими продуктами Microsoft жёстко прибит гвоздями к родному стеку, что значит, что для использования данного сервиса от вас потребуется как наличие VisualStudio, так и требование писать проект и тесты исключительно на Java. Но если вдруг у вас Java-стек (c MS VS), то цена вопроса — $99 за слот девайса в месяц, что сравнительно либерально.


Сервисы на выбор


AWS Device Farm



Ссылка.


Пожалуй, самая мощная ферма для тестирования на виртуальных и реальных устройствах на сегодняшний день (более 2500 устройств). Для нас это был приоритетный сервис, так как наши сервисы как раз развёрнуты в облаке AWS, кроме того, цены за минуту времени устройства начинаются от 17 центов. AWS позволяет работать как с нативными фреймворками, так и с Appium, Calabash, и другими фреймворками автоматизированного тестирования. Помимо автоматизированного тестирования, сервис предоставляет возможность ручной отладки. Ну и 1000 минут «на попробовать» — это очень заманчиво. Однако, дьявол как водится, кроется в деталях. С точки зрения тестирования у AWS есть несколько особенностей.


Мы, как я уже упомянул, используем Python 3.7, однако AWS Device Farm до сих пор работает с Python 2.7.6 (см. мануал здесь). И из коробки ничего не знает про tox. Для нас это означает отсутствие ряда возможностей и необходимость переработки части тестов для обеспечения обратной совместимости, так и создания окружения в обход tox. Кроме того, достаточно странный механизм загрузки тестового пакета (архив) подразумевает так же и загрузку приложения для тестирования. В нашем случае, если мы будем тестировать наш сервис через мобильный браузер, то загрузка приложения — лишний шаг. Впрочем, приложение можно заменить «заглушкой», а в окружении Python 2.7 создать venv с Python 3.7, и тогда в нём создать окружение с tox, который…



Amazon не был бы Amazon, если бы всё упиралось в старые версии. В качестве альтернативы (и ни у какого сервиса ниже такой возможности не будет) AWS предлагает использовать AWS Device Farm через AWS CLI (command line interface) (см. мануал здесь). То есть, мы можем подключить устройство из облака как реальное устройство к нашему компьютеру в режиме удалённой отладки (remote debug), правда, предварительно заменив adb на патченое (в списке бинарника под linux нет, но уверен, в природе он существует). То есть, настроив AWS CLI, для тестирования нам потребуется выполнить буквально несколько команд (ведь мы не собираемся использовать GUI в виде AWS Device Farm App).



Пример кода
import boto3  # используем AWS SDK https://pypi.org/project/boto3/

aws_client = boto3.client('devicefarm')
response = aws_client.list_devices()  # получим список доступных устройств
device_arn = ''
for phone in response["devices"]:
    if phone['name'] == "Google Pixel XL":  # ищем телефон по его имени (допустим оно уникально)
        device_arn = phone['arn']  # сохраняем его Amazon Resource Name
        break
project_arn = aws_client.list_projects()['projects'][0]['arn']  # просто берём первый наш проект из списка

# создаём сессию с поддержкой удалённой отладки, обязательно указываем публичный SSH ключ от устройства
response = aws_client.create_remote_access_session(projectArn=project_arn,
                                                   deviceArn=device_arn,
                                                   remoteDebugEnabled=True,
                                                   ssh-public-key=SSH_KEY)

# теперь в ответ на adb devices в списке должен появиться uuid Google Pixel XL из AWS Device Farm, аналогично для iOS

# вызываем наши тесты здесь
... RUN_TESTS() ...

# останавливаем и удаляем (если надо) сессию удалённой отладки
aws_client.stop-remote-access-session(arn=response['remoteAccessSession']['arn'])
aws_client.delete_remote_access_session(arn=response['remoteAccessSession']['arn'])

Если мы хотим тестировать приложение, его так же можно загрузить через AWS SDK.


Но я не рассказал ключевой нюанс здесь. Мы снова натыкаемся на дьявола в деталях. Дело в том, что опция удалённой отладки доступна только если для AWS мы используем Private Devices план. Во-первых, данная возможность доступна только под запрос (нужно написать письмо в Amazon), во-вторых опция доступна для региона us-west-2, а в-третьих, фактически эта опция нас возвращает к сценарию, когда у нас есть сервер для тестирования с набором (или хотя бы одним) устройств подключенных к нему. Плюсы очевидны — мы это устройство можем использовать монопольно, что очевидно безопаснее и быстрее, с другой стороны лишаемся главного преимущества — выбора и разнообразия устройств.


Сервис мне в целом понравился, но для нашей команды, увы, в нём слишком много «но».


Bitbar



Ссылка.


Эта облачная ферма мобильных устройств первая выпадает по запросу в поисковиках. И не зря. Забегая вперёд, скажу, что у данного сервиса лучший выбор устройств (только реальные устройства) и лучшая производительность в пересчёте на один тест в сравнении с другими. Bitbar предлагает услуги по удалённому ручному и автоматизированному тестированию (используя Appium и другие фреймворки), а так же, при желании позволяет использовать что-то похожее на crawler от Firebase Test Lab (Robot Test) — AI TestBot. Главное преимущество BitBar’a — это неограниченное количество потоков тестирования (то есть своё приложение можно сразу протестировать на сотне устройств), выбрав нужный пул устройств предварительно. Если устройство занято, подберётся другое такое же, либо сессия будет поставлена в очередь. По окончанию запуска тестов формируется лог, запись тестирования, результаты сохраняются, и уведомление отправляется на почту. Хотя есть и возможности настроить взаимодействие и с разными CI/CD инструментами. Так же сервис предоставляет возможность тестирования десктопных браузеров в разных разрешениях, а при желании — создания, как и в AWS, своих приватных устройств. Правда, за все эти фишки нужно платить — каждая минута тестирования обойдётся в $0.29.



Процесс настройки прост, как взаимодействие двух перстов с асфальтом:


Пример кода
from appium import webdriver

""" ... """

com_executor = 'https://appium.bitbar.com/wd/hub'
desired_capabilities = {
                        'deviceName': 'Motorola Google Nexus 6',
                        'deviceId': 'FA7AN1A00253',
                        'newCommandTimeout': 12000,
                        'browserName': 'Chrome',  #  для тестирования в мобильном Chrome, меняем или используем app
                        'bitbar_apiKey': 'BITBAR_API_KEY',
                        'bitbar_project': 'Software Testing',
                        'bitbar_testrun': 'Test run #N',
                        'bitbar_device': 'Motorola Google Nexus 6',
                        'bitbar_app': '23425235'
                        }
driver = webdriver.Remote(com_executor, desired_capabilities) 

""" ... """

Kobiton



Ссылка.


Ещё один сервис, предоставляющий услуги по тестированию на реальных устройствах. Выбор устройств скромнее Bitbar’a (350+), доступность устройств так же меньше. В целом очень похож по основному функционалу на BitBar, позволяет проводить ручное и автоматическое тестирование (с помощью Appium — тут без выбора фреймворков). Возможности потестировать на десктопных браузерах нет. Сервис так же позволяет организовать тестирование с неограниченным числом сессий и устройств, но пула устройств тут не создать. Цена на сервис очень либеральная — от $0.10 за дополнительную минуту тестирования, но во время пробного периода я обратил внимание на некоторую нестабильность сервиса — часто отваливался интернет на устройствах, один раз девайс повис. Так же, если устройство занято или забронировано, то все ваши запущенные тесты упадут. То есть, в отличие от Bitbar’a — очереди из сессий нет. Правда, с небольшими затратами её можно организовать. У Kobiton есть своё небольшое API.



Настройка так же очень проста, в отличие от bitbar’a почти что оригинальный Appium.


Пример кода
import base64
from time import sleep
from appium import webdriver
import requests

""" ... """

# авторизируемся
base64EncodedBasicAuth = base64.b64encode(bytes(f'{USERNAME}:{API_KEY}', 'utf-8'))
headers = {
  'Authorization': f'Basic {base64EncodedBasicAuth}'
}
reply = requests.get(f'https://api.kobiton.com/v1/apps', params={

}, headers = headers)

# теперь получим статус устройства deviceId
headers = {
  'Authorization': base64EncodedBasicAuth,
  'Accept': 'application/json'
}
reply = requests.get(f'https://api.kobiton.com/v1/devices/{deviceId}/status', params={

}, headers = headers)

# ждём по минуте, если устройство отключено или занято
while (reply['isOnline'] == False or reply['isBooked'] == True):
    sleep(60)

# настраиваем драйвер
com_executor = f'https://{USERNAME}:{API_KEY}@api.kobiton.com/wd/hub'
desired_capabilities = {
                        'browserName': 'Chrome',
                        # The generated session will be visible to you only.
                        'sessionName': 'Automation test session',
                        'sessionDescription': '',
                        'deviceOrientation': 'portrait',
                        'captureScreenshots': True,
                        'deviceGroup': 'KOBITON',
                        # For deviceName, platformVersion Kobiton supports wildcard
                        # character *, with 3 formats: *text, text* and *text*
                        # If there is no *, Kobiton will match the exact text provided
                        'deviceName': 'Pixel 2',
                        'platformName': 'Android',
                        'platformVersion': '9'
                        }
driver = webdriver.Remote(com_executor, desired_capabilities)

""" ... """

# выполняем тесты
RUN_TESTS()

""" ... """

# по завершению тестирования сессию лучше самостоятельно закрыть, чтобы не ждать таймаута (экономим время и деньги)

headers = {
  'Authorization': {base64EncodedBasicAuth}
}
requests.delete(f'https://api.kobiton.com/v1/sessions/{sessionId}/terminate', params={ })

""" ... """

BrowserStack



Ссылка.


Старый-добрый BrowserStack. О нём много чего писали и его много кто использует. Да, он позволяет проводить тестирование не только на разных браузерах, но и на разных устройствах. Как в ручном режиме, так и используя Selenium/Appium. В зависимости от потребностей — на мобильных браузерах или с использованием вашего приложения. По возможностям всё то же самое, что и у двух сервисов сверху, но в отличие от них здесь уже есть ограничения по количеству одновременных сессий. Правда, наоборот, платите $199 в месяц и тестируйте неограниченное время. Есть плагины для Jenkins, Travis CI, TeamCity, свой богатый API, отличные логи, и большой выбор устройств и десктопных браузеров на разных конфигурациях. Правда, в зависимости от того, чего вы тестируете будут различаться настройки — для тестирования браузеров (даже мобильных) используется Selenium хаб, а для приложений — Appium хаб. Более того, за тестирование приложения придётся платить отдельно. То есть, для того чтобы тестировать и мобильные браузеры, и приложения, нужно заплатить $199 и ещё $159 (цена за одновременно одно устройство для тестирования).



Пример кода для приложения
from appium import webdriver

""" ... """

com_executor = 'https://USERNAME:API_KEY@hub-cloud.browserstack.com/wd/hub'
desired_capabilities = {'device': 'Google Pixel',
                        'deviceName': 'Google Pixel',
                        'app': app_name,
                        'realMobile': 'true',
                        'os_version': '8.0',
                        'name': 'Bstack-[Python] Sample Test'
                        }
driver = webdriver.Remote(com_executor, desired_capabilities)

""" ... """

Пример кода для мобильного браузера
from selenium import webdriver

""" ... """

com_executor = 'http://USERNAME:API_KEY@hub.browserstack.com:80/wd/hub'
desired_capabilities = {'device': 'Google Pixel',
                        'deviceName': 'Google Pixel',
                        'browserName': 'Chrome',
                        'realMobile': 'true',
                        'os_version': '8.0',
                        'name': 'Bstack-[Python] Sample Test'
                        }
driver = webdriver.Remote(com_executor, desired_capabilities)

""" ... """

Experitest



Ссылка.


Ещё один сервис, который предоставляет возможность тестирования в ручном и автоматическом режиме как мобильных устройств, так и десктопных браузеров с использованием Appium, Selenium и других фреймворков. Как и в случае с BrowserStack’ом, количество одновременных сессий ограничено, но цены немного иные — за тестирование мобильных приложений сервис просит $199 за месяц, а за кроссбраузерное тестирование всего $39 (за одну одновременную сессию). Кроме того, как и Bitbar c AWS позволяет собрать свою приватную лабораторию с устройствами, которые, впрочем, при желании можно миксовать и с публичным облаком из тысячи устройств, эмуляторов и браузеров разных версий и платформ (MacOS, Windows). Из интересных особенностей — наличие расширений для IntelliJ и Eclipse, своего инструмента Appium Studio, который позволяет использовать расширенный функционал устройств вроде взаимодействия c FaceID, управления голосом, сканирования штрих-кодов, установки качества связи, геопозиции и прочая. Из минусов могу назвать странный набор устройств для пробного периода, драконовскую тарификацию на пробном периоде, а так же требование использовать корпоративную почту (gmail не подойдёт).



Пример кода
from appium import webdriver

""" ... """

com_executor = 'https://Uhttps://cloud.seetest.io/wd/hub'
desired_capabilities = {"deviceName": "iPhone X",
                        "accessKey": API_KEY,
                        "platformName": "ios",
                        "deviceQuery":  "'@os='ios' and @version='12.1.3' and @category='PHONE'",
                        }
driver = webdriver.Remote(com_executor, desired_capabilities)

""" ... """

SauceLabs



Ссылка.


Один из старейших сервисов облачного тестирования. Почти 400 разных реальных устройств, богатый выбор симуляторов и эмуляторов, включая нетипичные эмуляторы устройств Samsung, есть и десктопные браузеры под разные ОС, включая Linux. Автоматизация на Appium/Selenium и нативных фреймворках. Главный плюс сервиса — наличие обширной коллекции конфигураций в том числе и старых ОС, браузеров, устройств. SauceLabs так же имеют ограничение в количестве одновременных сессий, но тут самый дешевый вариант включает не одну, а две одновременных сессии. Что необычно: тарифные планы на реальных устройствах и на эмуляторах отличаются. Так, самые дешевые варианты, включающие в себя две сессии с 2000 минутами тестирования в месяц на эмуляторах обойдутся в $149, а на реальных устройствах уже в $349. Есть интеграция с CI/CD, Slack.К сожалению, попробовать вживую SauceLabs мне не удалось, так как увы, не проходит регистрация, возможно из-за региона, но точно утверждать не берусь.


Perfecto



Ссылка.


Последний провайдер облачного тестирования визуально больше всего похож на Experitest, но без расширенного функционала. Есть свой простой скриптовый язык. Очень странно, но в сервисе для не-корпоративных (Enterprise) тарифов нет предложения для тестирования на десктопных браузерах, так же нельзя наблюдать за выполнением тестов в реальном времени (только если это не ручное тестирование). В распоряжении к тестированию доступно порядка ста разных устройств. Есть интеграция с Jenkins, а так же, что интересно, с инструментами тест-менеджмента вроде HP ALM, IBM Rational, TFS. Так же в наличии весьма странные тарифные планы, вроде 5 часов тестирования в месяц (в пересчёте на минуты аж $0,33 (это самый дорогой сервис)), правда с возможностью докупить пакет с дополнительными часами, но опять-таки, странно, что нет поминутной или хотя бы почасовой тарификации по факту. Что же касается удобства использования, то во время пробного периода доступно только ручное тестирование, а так же общая лаборатория, так что все запуски от разных пользователей сваливаются в одну кучу. Так что судить точно об удобстве и скорости сервиса, увы, нельзя. Видно, что сервис в основном ориентирован на крупных корпоративных клиентов, при этом, по крайней мере по имеющейся информации, возможности у данного провайдера самые скромные из всех мною протестированных.




Сводные результаты


По всем критериям выбора сервисы весьма схожи, разница между сервисами в их производительности и цене (если нет особенностей, например, как в случае AWS). Поэтому сведём данные исследования в таблицу, посмотрим на скорость сервисов (с учётом подключения через US VPN), а так же на цену, для удобства сравнивая среднее месячное время тестирования на устройствах (5 релизов в месяц, по 2 часа тестирования на Android и iOS устройстве = 20 часов). В качестве референсных значений я использую данные со своего локального компьютера с эмулятором, опять-таки подключаясь к нему для чистоты эксперимента через VPN в США).



Выводы


Для меня было достаточно любопытно поисследовать и выбрать подходящий сервис для нашей команды. В целом, есть решения на любой вкус и под любые задачи, а по характеристикам и реализации сервисы весьма оказались похожи. В итоге, в зависимости от ваших задач я бы порекомендовал следующий выбор:


Вариант А: Если вам важна быстрота проверки, и нужны проверки сразу на десятках разных устройств — ваш выбор — Bitbar.


Вариант Б: Если у вас в приоритете результаты с референсных устройств, а конфигурационное тестирование вторично (но необходимо) — ваш выбор — BrowserStack. Это как раз наш кейс, так как статистически — 90% всех ошибок — это ошибки с референсных платформ и устройств (чаще всего баги общие для всех референсных платформ сразу). Оставшиеся 8% — это ошибки MS IE, с отказом от поддержки IE — 2% ошибки MS Edge, а 0,5% ошибки на специфичных конфигурациях.


Вариант В: Если вам важны проверки особых условий, вроде некачественной связи, геопозиции или Touch/FaceID, то ваш выбор — Experitest.


Ну а на долгосрочной перспективе, если ваша компания занимает большой офис, ваша работа Full-Time, то, как правило, организация своей, пусть даже мини-лаборатории с сервером под эмуляторы с подключенными 2-3 устройствами обойдутся дешевле и удобнее, чем использование специализированных сервисов.