Сегодня, когда в кармане у каждого жителя мегаполиса есть компьютер, который может куда больше, чем долететь до луны, мы пользуемся мобильными приложениями каждый день. Новости, погода, акции, шопинг — все эти функции реализованы в сотнях тысяч приложений. Но если любимое приложение подвисает или крашится — оно быстро перестает быть любимым.
Это статья написана ребятами из WaveAccess
Мы разрабатываем мобильные приложения более 10 лет, и никак не можем позволить себе выпускать продукт, который бажит в руках пользователей. Именно поэтому “качать” команду тестирования и инфраструктуру для нас не менее важно, чем другие области.
Сотни Android-девайсов, iPhone с различными версиями ОС, разная диагональ устройств ставят перед QA-инженерами задачу “отлавливать” дефекты и на реальных мобильных устройствах, и на различных версиях операционных систем. Но прогонять один и тот же ручной сценарий на 10, 20, 50-ти устройствах мало кому под силу. Именно благодаря таким задачам мы прокачали свой навык автоматического тестирования, особенно, на мобильных устройствах. Но будем честны: создать и поддержать инфраструктуру даже с 20-ю реальными девайсами для прогона автотестов — это головная боль.
В этой статье хотим рассказать, как попробовали новый для себя сервис Microsoft App Center для проверки качества разрабатываемого нами приложения на зоопарке реальных девайсов.
Почему встал вопрос использования сервиса
Сейчас мы разрабатываем приложение для сопровождения шоппинга. Проект идет давно: заказчик постоянно предлагает какие-то новые фичи, идет за разработкой только к нам. В приложении уже десятки экранов, от “купить” до различных вариантов сообщений, пушей, функций типа “собери свой лук”. И все это время происходят презентации проекта инвесторам, запуски в новых торговых центрах, так что чем выше скорость релиза (без падения качества продукта) — тем лучше.
До сего времени мы запускали автотесты на ограниченном количестве устройств, которое было в нашем распоряжении (для этого проекта — порядка 30-ти Android-девайсов и “яблок”). Сейчас приложение выходит на новый уровень, аудитория выросла, и качество стало еще более критичным. Встал вопрос об использовании облачного сервиса для прогона автотестов на большем количестве разных устройств.
В процессе релизов хотелось пользоваться всеми современными и доказавшими свою полезность практиками разработки ПО: кросс ревью, непрерывная интеграция, автоматизированное функциональное и модульное тестирование на большом списке девайсов на iOS + Android, сбор аналитики и крешлитики (crashlytics).
Каждую из этих практик мы применяли ранее и по отдельности, и в комплексе. Но с учетом масштабов проекта и большого размера команды, хотелось получить универсальное решение. Пусть инструмент умеет все перечисленное и может в одном месте предоставить возможность управлять состоянием разработки и доставки мобильных приложений для разных платформ и мониторить его.
От каждого из ролей в команде были свои условия: разработчики не хотели менять уже налаженный процесс разработки (репозиторий, билд тул и т. д.), а также переходить на слишком новые, непроверенные инструменты в проде. Инженеры по тестированию мечтали о снижении нагрузки по проверке на зоопарке девайсов, менеджерам и заказчику хотелось удобный интерфейс для мониторинга всего состояния с прозрачным флоу.
Исследование аналогов — довольно важный этап при выборе инструмента. Мы смотрели разные сервисы, предоставляющие такие возможности (для Appium-тестов, например, BrowserStack). В случае с Microsoft App Center нам предоставили триальный период, поэтому у нас была возможность попробовать и понять, что будет с проектом, если уделять качеству чуть больше ресурсов и автоматизировать весь релиз-процесс мобильного приложения для любой платформы одним сервисом. Рассказываем, как это было.
Как настроить iOS app
Итак, воспользовавшись триальным периодом, который не накладывает ограничений в функционале, создаем свое iOS приложение в Microsoft App Center:
Выбираем платформу:
Добавляем App Center SDK в проект:
pod 'AppCenter'
После установки подов открываем файл AppDelegate.swift и добавляем следующие строки под своей собственной командой импорта:
import AppCenter
import AppCenterAnalytics
import AppCenterCrashes
В том же файле добавляем в метод didFinishLaunchingWithOptions следующие строки:
MSAppCenter.start("{Your App Secret}", withServices:[
MSAnalytics.self,
MSCrashes.self
])
Аналогичный процесс — для objective C, полная версия инструкции — здесь.
Билдим!
Переходим во вкладку Build, выбираем наш сервис svc.
Конфигурируем билд. Не забываем подписать, так как это генерирует нам файл приложения формата app, который можно запускать на реальных девайсах:
Готово! Нажимаем кнопку Build now и ждем сборки.
Аналогичная история для Android приложений, инструкция — здесь.
Запускаем первые тесты для iOS
Unit- и нативные тесты для каждой платформы можно включить в сборку (есть галочка). О функционале АТ на разных девайсах рассказываем далее.
Настройка сета девайсов iOS, Android, отправка тестов на сет
Переходим на вкладку Test, Device Sets. Создаем набор девайсов, на которых будем гонять наши тесты. На выбор есть более 250 Android девайсов и более 200 различных iOS девайсов (generation version + iOS version). Подробный список устройств — тут.
Здесь несколько огорчило, что официальный ответ на вопрос, как скоро после релиза появятся новые Apple девайсы, звучит как “1-2 месяца после поступления в продажу”.
Готовим тесты к запуску в App Center (пример для XCUITest) и отправим на запуск. В App Center есть возможность билда только приложения, так что билдить проект тестов все же придется локально у себя на машине или в своем CI.
Shell:
# Generate an XCUITest bundle and your iOS application as described above.
$ rm -rf DerivedData
$ xcrun xcodebuild build-for-testing -derivedDataPath DerivedData -scheme YOUR_APP_SCHEME
# Upload your test to App Center
$ appcenter test run xcuitest --app "<app center username/<app name>" --devices DEVICE_SET --test-series "master" --locale "en_US" --build-dir DerivedData/Build/Products/Debug-iphoneos
Appium-тесты
Стоит убедиться, что используемые фреймворки тестов соответствуют поддерживаемым. Кроме того, необходимо использовать драйвер, предоставляемый App Center, а это накладывает свои ограничения по использованию фреймворков (например, Google Giuce использовать не получится).
Билд проекта для пользователей Maven
Шаг 1. Добавляем репозиторий и зависимости
Нужно будет добавить в файл pom.xml репозиторий JCenter.
XML
<repositories>
<repository>
<id>jcenter</id>
<url>https://jcenter.bintray.com/</url>
</repository>
</repositories>
Затем добавляем зависимость для расширений Appium-тестов
XML
<dependency>
<groupId>com.microsoft.appcenter</groupId>
<artifactId>appium-test-extension</artifactId>
<version>1.3</version>
</dependency>
Таким образом, во время компиляции будут доступны расширенные драйверы Android и iOS (которые нужны, прежде всего, для реализации фичи “label”; о ней подробнее в Шаге 4).
Шаг 2. Добавляем загрузочный профиль
Копируем сниппет в свой pom.xml в <profiles>. Если в pom-файле отсутствует секция <profiles>, нужно ее создать. Профиль после активации пакует наши тестовые классы и все зависимости в папку target/upload, готовую для загрузки в TestCloud.
Билд для пользователей Gradle
Шаг 1. Репозиторий и зависимости
Убеждаемся, что в build.gradle в корневой папке проекта активирован репозиторий JCenter:
gradle
allprojects {
repositories {
jcenter()
}
}
Добавляем следующий сниппет в build.gradle в папке приложения:
gradle
androidTestCompile('com.microsoft.appcenter:appium-test-extension:1.0')
Начиная с версии Gradle 3.0, androidTestCompile является устаревшим. Вместо него нужен androidTestImplementation.
Шаг 2. Автоматизируем генерацию pom-файла
Чтобы аплоадер заработал, требуется файл pom.xml. Добавляем в build.gradle в папке приложения следующий сниппет, чтобы pom-файл собрался автоматически:
gradle
apply plugin: 'maven'
task createPom {
pom {
withXml {
def dependenciesNode = asNode().appendNode('dependencies')
//Iterate over the compile dependencies (we don't want the test ones), adding a <dependency> node for each
configurations.testCompile.allDependencies.each {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', it.group)
dependencyNode.appendNode('artifactId', it.name)
dependencyNode.appendNode('version', it.version)
}
def profilesNode = asNode().appendNode('profiles')
profilesNode.append(new XmlParser().parse('https://raw.githubusercontent.com/Microsoft/AppCenter-Test-Appium-Java-Extensions/master/gradleuploadprofilesnippet.xml'))
}
}.writeTo("pom.xml")
Изменения в тестах
Шаг 1. Добавляем импорты
Импортируйте пакеты в свои тест классы:
Java
import com.microsoft.appcenter.appium.Factory;
import com.microsoft.appcenter.appium.EnhancedAndroidDriver;
import org.junit.rules.TestWatcher;
import org.junit.Rule;
Шаг 2. Создаем экземпляр TestWatcher
Добавляем в каждый тест-класс JUnit Rule (или в базовый класс тестов):
Java
@Rule
public TestWatcher watcher = Factory.createWatcher();
Шаг 3. Меняем тип драйвера
Поменяйте тип драйвера при его объявлении или с AndroidDriver<MobileElement> на EnhancedAndroidDriver<MobileElement>, или с IOSDriver<MobileElement> на EnhancedIOSDriver<MobileElement>
Java
private static EnhancedAndroidDriver<MobileElement> driver;
Шаг 4. Обновляем экземпляры драйверов
Меняем инстансы драйвера таким образом, чтобы строки вида:
Java
driver = new AndroidDriver<MobileElement>(url, capabilities);
… поменялись на вид:
Java
driver = Factory.createAndroidDriver(url, capabilities);
Использование этих драйверов по-прежнему позволит запускать тесты локально без дополнительных модификаций, но в дополнение позволит добавлять “label” на шаги в исполняемом тесте, используя driver.label(«ваш текст»). Текст и скриншот с девайса будут доступны в тест-репорте в Test Cloud. Весьма рекомендуется делать обращение к метке через метод After, поскольку это добавит скриншот последнего состояния приложения в тест-репорт.
Скриншот будет сделан, даже если тест провален. Как правило, в нем достаточно информации, чтобы понять, почему так случилось. Пример реализации в методе After:
Java:
@After
public void TearDown(){
driver.label("Stopping App");
driver.quit();
}
Загрузка в App Center test
Процесс загрузки по шагам:
- Генерируем команду App Center Test upload. Документация (EN) — starting a test run.
- Пакуем тест-классы и все зависимости в папку target/upload
shell:
- mvn -DskipTests -P prepare-for-upload package
- Загрузка и запуск тестов начался
По завершении можем просмотреть результаты на каждом девайсе из списка:
Скрины с результатами, логи, отчет
На каждом из iOS или Android девайсов можно просмотреть подробный лог и скриншот для диагностики падения теста:
А также статистику всех запусков за интервал времени:
Правда, доступ к “девайсу” для дебага и инспекции не предоставляется. Если с тестами что-то идет не так и логов недостаточно — все решается только через поддержку. В одном из популярных сервисов по запуску АТ на девайсах — BrowserStack — такая возможность есть, и она встроена в Appium. Можно было бы отдать URL и порт для создания подключения к серверу девайсов.
Выводы
Удивительно, но весь релизный процесс от Continuous Integration до Continuous Delivery приложения обеспечивается в одном месте: Microsoft App Center предлагает CI build, test, deploy to store, analytics, crashlytics.
Попробовав меньше половины предложенного функционала, команда вынесла приятное впечатление. Из очевидных плюсов: не нужно писать поддержку для каждого девайса в виде кода. Ну и прочие плюшки радуют:
- Не нужно поднимать сервер для толпы девайсов.
- Не нужно подключать к этому серверу 100500 девайсов.
- Не нужно жить с глюками андроида когда он включен 24\7.
- Не нужно собирать контейнер под девайс, не нужно менеджить эти контейнеры.
- Не нужно мириться с ограниченностью эмуляторов.
Microsoft App Center нас устроил по изначальным параметрам: он очень не требователен в плане интеграции, но предоставляет все запрашиваемые функции, избавляя от трудной поддержки. Планируем использовать сервис на проекте, так как задачи инструментария при обеспечении качества он решает.