Всем привет! Я Алексей Пак, работаю в отделе автоматизации компании «ГПМ Цифровые Инновации». Занимаюсь ручным и авто тестированием 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
-
В разделе Variables создаем 3 переменные:
ALLURE_ENDPOINT – адрес Allure TestOps сервера, например http://allure.company.com).
ALLURE_TOKEN - Allure TestOps token
ALLURE_PROJECT_ID – ID проекта Allure TestOps
Подробнее смотреть здесь.
Переходим к заключительной части и создадим скрипты для запуска автотестов.
-
Создание джобы
Теперь настроим 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 можно увидеть отчет
Официальная документация здесь.
В статье мы познакомились с тем, как настроить интеграцию между автотестами на 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