Всем привет! Я Алексей Пак, работаю в отделе автоматизации компании «ГПМ Цифровые Инновации». Занимаюсь ручным и авто тестированием Android приложения онлайн-кинотеатра PREMIER.
После внедрения Allure TestOps и автотестов на Kaspresso перед нашей командой встала новая задача. Как настроить запуск наших тестов в CI/CD? В статье расскажу про настройку интеграции между Kaspresso, Allure TestOps и Gitlab CI. Поделюсь опытом про проблемы с которыми столкнулись и как решали их, чтобы вы смогли самостоятельно настроить тестовую среду не наступать на грабли)
Статья будет интересна тем, кто задумывался о запуске автотестов в CI/CD и получении отчетов в Allure Test Ops и тем, кто на пути внедрения тестовой инфраструктуры. Для автоматизации тестирования приложения пишем нативные автотесты на Kotlin. В нашем проекте для Android приложения используем Kaspresso, Junit, Allure Test Ops, Gitlab CI/CD
Kaspresso - гибкий и удобный фреймворк фреймворк для автоматизации UI. Фреймворк представляет обертку Espresso, UI Automator. Мы выбрали этот фреймворк, тк содержит следующие преимущества:
- Хорошая читаемость кода теста 
- Решение для flaky-тестов 
- Расширенное логирование 
- Работа с AdbServer 
- Запись видео/создания скриншотов 
Также мы используем различные дополнительные возможности Kaspresso. Такие как отключение wifi и сети передачи данных для проверки приложения в оффлайне, эмуляцию звонков/смс и многое другое. Можно посмотреть полный список.
Allure TestOps - позволяет писать тест-кейсы для ручного и авто тестирования. Дополнительно заводить дефекты, смотреть отчеты, управлять прогонами.
Приступим к настройке интеграции Allure TestOps и Gitlab CI по шагам:
- Загрузка результатов тестов из Gitlab 
- Аутентификация Gitlab сборки 
- Настройка GitLab проекта для загрузки тестовых данных 
- Создание скрипта сборки 
Загрузка результатов тестов из Gitlab
GItlab загружает тестовые данные с помощью allurectl. Allurectl — это утилита командной строки для API Allure TestOps. Загружает результаты тестирования из пайплайна и управляет действиями в Allure TestOps (тест-кейсы, прогоны, проекты).
Аутентификации Gitlab сборки.
Настраиваем аутентификацию в TestOps и GitLab. Для этого нужно сгенерировать secret token и прописать в настройках CI/CD:
- Авторизуемся в TestOps под личной учетной записью. 
- Переходим в профиль 

- В разделе API tokens нажать на Create 

- Вводим название ALLURE_TOKEN и Submit 

- Сохраняем secret token. 
- Далее переходим к созданию переменных в Gitlab для привязки к Allure TestOps. 
Настройка GitLab проекта для загрузки тестовых данных
Добавляем информацию об Allure server в настройки Gitlab.
- 
Переходим в настройки проекта CI/CD  Переход в раздел CI/CD - 
В разделе Variables создаем 3 переменные: - ALLURE_ENDPOINT – адрес Allure TestOps сервера, например http://allure.company.com). 
- ALLURE_TOKEN - Allure TestOps token 
- ALLURE_PROJECT_ID – ID проекта Allure TestOps 
 Подробнее смотреть здесь. 
  Раздел Variables - Переходим к заключительной части и создадим скрипты для запуска автотестов. 
 
- 
Создание джобы
Теперь настроим pipeline в gitlab. Создаем файл .gitlab-ci.yml в корне проекта. В этом файле находятся скрипты для CI/CD.
В нашем примере рассмотрим запуск smoke автотестов вручную по кнопке. Так выглядит готовый скрипт для наших автотестов.
 smokeTests:
  when: manual # запуск только вручную
  stage: test # стейдж сборки приложения
  before_script: # стейдж сборки приложения
	- adb start-server > /dev/null # запускаем adb-server 
	- ${ANDROID_HOME}/emulator/emulator -avd test -no-window -no-audio -no-boot-anim -logcat '*:s' & adb wait-for-device > /dev/null # запускаем эмулятор
	- adb devices # отображаем наш эмулятор
	- adb shell settings put global window_animation_scale 0 & # отключаем анимацию
	- adb shell settings put global transition_animation_scale 0 &
	- adb shell settings put global animator_duration_scale 0 &
	- /android-wait-for-emulator
	- adb shell input keyevent 82
	- wget https://github.com/allure-framework/allurectl/releases/download/2.2.1/allurectl_linux_amd64 -O ./allurectl
	- chmod +x ./allurectl
  script:
	- ./gradlew :app:installGoogleDebug :app:installGoogleDebugAndroidTest  # устанавливаем сборку
	- adb shell input keyevent 82
- adb shell am instrument -w -e package com.android.test.package com.android.test/com.kaspersky.kaspresso.runner.KaspressoRunner >  tests.log # запускаем тесты
- adb pull sdcard/Documents .# сохраняем данные о прогоне
- adb shell rm -rf /sdcard/Documents/logcat # очищаем тестовые данные
- adb shell rm -rf /sdcard/Documents/screenshots
- adb shell rm -rf /sdcard/Documents/video
- adb shell rm -rf /sdcard/Documents/view_hierarchy
- ./allurectl upload Documents # выгружаем тестовые данные на в Allure TestOps
 artifacts:
  expire_in: 1 week # время жизни артефакта, у нас он должен храниться только 1 неделю
  paths:
	- /builds/com.android.test /android/tests.log # путь к артефактам
 after_script:
  - >
	if grep -w 'FAILURES!!!' tests.log; then
  	curl -X POST $TELEGRAMM_CHAT"text=Project:+$CI_PROJECT_NAME+$CI_PROJECT_URL/pipelines/$CI_PIPELINE_ID/ Branch:+$CI_COMMIT_REF_SLUG - has FAILED!"
	else
  	echo 'This will only run on success'
	fi
- before script. Этот блок используется для предусловий, те команд выполняющихся до запуска основного скрипта. 
- script. Блок script используется для команд, которые выполняются на раннере. Основные команды находятся в этом блоке, например запуск автотестов. 
- after script. Команды в этом блоке выполняются после основных команд. 
Давайте разберем некоторые команды подробнее.
Мы используем кастомный докер с эмулятором. Также можно найти готовый образ и добавить через before_script. Запускаем эмулятор с ключами.
- ${ANDROID_HOME}/emulator/emulator -avd test -no-window -no-audio -no-boot-anim -logcat '*:s' & adb wait-for-device > /dev/nullПро запуск эмулятора и команды можно найти здесь.
Обратите внимание allurectl может работать в 2х режимах: Non-CI mode и CI mode. Мы разберем второй вариант.
Скачиваем allurectl для выгрузки отчетов в Allure Test Ops
    - wget https://github.com/allure-framework/allurectl/releases/download/2.2.1/allurectl_linux_amd64 -O ./allurectl
    - chmod +x ./allurectlУстанавливаем нужную сборку на эмулятор смартфона. Обратите внимание на вторую часть, это сборка с нашими тестами. Ее необходимо поставить, чтобы тесты запустились.
./gradlew :app:installGoogleDebug :app:installGoogleDebugAndroidTestНаши коллеги рассказывали подробно про сборки.
С запуском тестов немного пришлось помучаться. Но мы решили следующим образом. В данном примере запускаются все тесты в папке com.android.test.package. Также мы используем раннер KaspressoRunner для запуска тестов
 adb shell am instrument -w -e package com.android.test.package com.android.test/com.kaspersky.kaspresso.runner.KaspressoRunner >  tests.logВывод передаем в файл tests.log, тк может возникнуть ошибка при очень большом логе.
Официальная документация по тестированию из командной строки.
Далее нам нужно из папки скопировать данные о прохождении теста. В kaspresso версии 1.4.2 данные создавались в папке /data/data/packagename/files и нужны были права администратора для копирования данных.
В kaspresso 1.5.1 данное поведение исправили и данные сохранятся в папке
sdcard/Documents
Сохраняем папку из девайса
 adb pull sdcard/Documents .Загружаем отчеты тестирования на наш сервер Allure TestOps
./allurectl upload DocumentsПосле отправки отчетов нужно удалить файлы на эмуляторе, тк они занимают много места.
- adb shell rm -rf /sdcard/Documents/logcat
- adb shell rm -rf /sdcard/Documents/screenshots
- adb shell rm -rf /sdcard/Documents/video
- adb shell rm -rf /sdcard/Documents/view_hierarchyВ таком формате публикуется прогон

- 
Далее запускаем наш пайплайн  Запуск пайплайна 
- 
В логах можно увидеть ссылку на прогон в Allure  Данные о пайплайне 
- 
После завершения прогона в Allure TestOps можно увидеть отчет  Отчет в Allure 
Официальная документация здесь.
В статье мы познакомились с тем, как настроить интеграцию между автотестами на Kaspresso, Allure TestOps и Gitlab CI и как сделать запуск автотестов в CI/CD. Теперь вы сможете настроить автоматический прогон тестов по расписанию или по триггеру и наслаждаться отчетами в Allure)
На этом мы с вами не прощаемся и в следующий раз можем рассказать более подробно про сборку эмулятора или архитектуру наших тестов.
Хотелось выразить огромную благодарность авторам и сообществу Kaspresso за активную помощь.
P.S. Бонус для тех кто дочитал до конца
Если сейчас запустить наш пайплайн, то он пройдет успешно. Но в прогоне могут быть упавшие тесты. Дело в том, что после запуска нашей джобы она всегда проходила успешно и при падении тестов мы не видели статуса failed. Для этого мы написали небольшой скрипт, который отправляет результаты прогона в телеграмм. Сохраняем лог и ищем ключевое слово FAILURES - падение тестов. В данном мессенджере у нас создан канал и после завершения pipeline результаты публикуются ботом. Настройку интеграции gitlab и телеграмма можно сделать по официальной документации.
after_script:
  - >
	if grep -w 'FAILURES!!!' tests.log; then
  	curl -X POST $TELEGRAMM_CHAT"text=Project:+$CI_PROJECT_NAME+$CI_PROJECT_URL/pipelines/$CI_PIPELINE_ID/ Branch:+$CI_COMMIT_REF_SLUG - has FAILED!"
	else
  	echo 'This will only run on success'
	fi 
          