Backend Client как универсальный инструмент для UI-автотестов
Всем привет!
В этой статье я бы хотел поделиться инструментом, который мы в Okko используем для UI-автотестов для клиентских приложений платформы Android.
Обычно, когда в компаниях начинают задумываться о UI-тестах, первой вехой такой автоматизации являются чистые e2e-тесты. Это уже хороший результат, но, к сожалению, как только наше покрытие начинает выходить за рамки того, что можно сделать толькочерез клиент, начинаются большие проблемы.
Также по мере расширения покрытия мы начинаем сталкиваться с проблемой времени выполнения тестов, которое может легко составлять и несколько часов, поскольку для каждого кейса мы должны заново прокликивать на клиенте все предусловия для какой-либо из проверок.
И соответственно, чем больше мы этим занимаемся, тем выше вероятность падения UI-тестов, поскольку в идеальном мире взаимодействия с клиентом должно быть ровно столько, сколько необходимо для выполнения теста, а у нас же получается всё наоборот. Поэтому после того, как такие тесты уже написаны, все начинают задумываться, а не начать ли применять к фронтовым тестам что-нибудь из бэкенда. Мы столкнулись с этой же проблемой.
В статье я расскажу, как можно выйти из этого положения, причем данный опыт можно применить и превентивно, еще до того, как будут написаны ваши первые тесты.
Backend Client
Мы пришли к весьма универсальной штуке, и особо не заморачиваясь по поводу её названия, назвали её Backend Client.
Ранее в компании этот инструмент уже существовал в ограниченном виде как библиотека для backend-тестировщиков, имел внутренние зависимости и прочие заморочки. Мы взяли эту библиотеку, вытащили в отдельную сущность, дописали необходимый фронту функционал, и превратили в такую штуковину, которой теперь могут пользоваться все, в том числе и мы — автоматизаторы клиентских приложений.
Мультиплатформенная структура
Мы используем данный инструмент для UI-автотестов на трёх платформах: Web, Android и iOS. Тесты на первые две платформы написаны на python — на них клиент бэкенда доступен как python-библиотека, поэтому достаточно просто импортировать её в проект. Автотесты для iOS написаны на Swift«е (фреймворк XCUITest), и для этой платформы потребовалось написать CLI-обработчик, через который и происходит работа с backend.
Импорт, инициализация, вызовы
В автотестах на Python мы выполняем инициализацию нашего клиента через фикстуру pytest, и таким образом получаем к нему доступ с любого места в коде. На Swift же всё чуть сложнее — здесь используется внешний вызов шелл-скрипта, в котором уже проворачиваются нужные делишки.
Сейчас мы пользуемся нашим инструментарием на PRE-PROD окружении (то есть, тестовом), что в теории позволяет нам проводить манипуляции с любыми данными без вероятности сломать PROD. О последнем я напишу ниже, так как интеграция на продакшне такого вида включена в roadmap на дальнейшее развитие.
Функциональность
Для наглядности я объединил все возможные функции в группы и разбил их на три большие секции:
В первой группе находится всё, что относится к пользователям сервиса. Теперь мы можем выполнять любые операции с аккаунтами — создавать, удалять, редактировать информацию, выполнять слияние аккаунтов (так называемый мердж) и делать всё это до, или в момент выполнения тестов.
Во вторую группу попало всё, связанное с контентом. Мы можем играться с, так называемым, мешком пользователя — менять контент, который он добавил в избранное, рекомендации и историю просмотров, проверяя сразу кучу сценариев. Мы даже можем изменять сохранённое время просмотра для отдельной единицы контента в качестве предусловия теста — это нужно потому, что логика поведения приложения у нас разная в зависимости от того, начинал пользователь просмотр, или еще нет.
Третья группа — пожалуй, самая важная, потому что напрямую связана с прибылью нашего кинотеатра. Можно проверить доступность и корректную работу каждой модели монетизации, а также управлять балансом и привязкой банковских карт.
Для чего это нужно
Создание предусловий
Подготовка тестового окружения, недоступного для клиента, стала возможной. Теперь то, что нельзя было сделать из UI приложения, и требовало ручной подготовки предусловий, можно сделать в качестве предусловия автотеста. Ручная «подгонка» тестовых данных больше не требуется.
На картинке выше мы абстрактно создаём пользователя из Казахстана в автоматическом режиме, перед тестом навешиваем ему нужные параметры, чтобы проверить, как приложение ведёт себя при покупке контента с этими настройками.
Сокращение времени автотестирования
Состояние приложения, которое ранее задавалось через UI, теперь можно задать за пару команд либо как предусловие теста, либо прямо во время его выполнения.
На картинке выше показан пример, в котором нам нужно выполнить какой-либо тест на пользователе с определённой подпиской. В случае, если бы мы использовали только UI, подготовка окружения заняла бы на три шага больше. Ниже будет продемонстрирован наглядный пример похожего тестового кейса из практики, во сколько раз мы ускорили автотесты благодаря нашему Backend Client.
Уменьшение количества flaky-тестов
Перенос большей части действий на бэкенд повышает стабильность UI-автотестов, поскольку в последних всегда присутствуют факторы, которые внезапно могут дать сбой. Применяя такую практику с переносом, мы получаем:
меньшее количество действий с клиентским приложением (т.е. вероятность пропустить команду устройством меньше, если меньше самих команд)
меньшее число взаимодействий с клиентом позволяет уменьшить количество потенциальных ошибок фреймворка клиентской автоматизации
если мы говорим о тестировании на реальных устройствах, то если подготовка условий для теста происходит со стороны backend, то мы не используем беспроводную сеть, в которой расположено устройство, исключая потенциальные сетевые потери.
На картинке выше представлен реальный пример «до и после» из нашего приложения для Android TV. Ранее для авторизации по PIN-коду требовалось запускать на машине внешний браузер, подсовывать ему нужного пользователя и только после этого авторизироваться. Теперь мы делаем это через бэк, и всё работает гораздо стабильнее.
Работа с логами backend
Также в нашем инструменте присутствуют различные вспомогательные модули и утилиты, в том числе для поиска ошибок в логах, которые отправляют backend-микросервисы во время работы тестов. Другими словами — параллельно проверкам, что UI приложения корректно отрабатывает сценарий, мы также можем отслеживать, не случилось ли на бэке при этом чего-то подозрительного. И если оно случилось, то можем достать эту информацию из местного Elasticsearch и прикрепить к упавшему тесту, чтобы облегчить QA дальнейший т.н. research, и идти искать корень проблемы в нужном направлении.
Инструмент для ручного тестирования
Manual QA вместо того, чтобы вручную формировать окружение для тестов, могут воспользоваться CLI-утилитой и делать это выполнением одного скрипта. Эта штука может облегчить рутину и сократить однотипные действия с бэкендом до минимума, чтобы специалист мог заниматься непосредственным тестированием, не тратя время на долгую настройку предусловий.
О пользе — наглядно
Вы можете наглядно увидеть, насколько у нас получилось улучшить отдельно взятые тесты. Сперва поговорим о приросте скорости. Возьмём реальный тест-кейс, где нам требуется проверить, что каждая из купленных подписок открывает дступ для определённого контента:
Видео с тестами у нас будут ускорены в 10 раз. Для того чтобы обойтись только UI-тестами, которые мы видим слева — нам необходимо:
зарегистрировать нового пользователя
привязать на аккаунт тестовую карту
приобрести нужную подписку
и только затем проверить, открылся ли требуемый контент для просмотра.
Справа мы видим, как этот же кейс выполняется с использованием Backend Client«а, где требуется гораздо меньшее количество UI-действий, которое нужно совершить на конечном устройстве. Перед каждой итерацией теста мы просто удаляем старую подписку с аккаунта, и добавляем новую, при этом нам даже не приходится проходить повторную авторизацию на клиенте.
В сухих цифрах по времени выполнения теста, мы получаем семь с половиной минут на левый сценарий, и менее минуты — на правый. Прирост в скорости весьма значительный.
Также мы для статистики прогнали оба кейса аж по сто раз каждый, и получили следующие результаты стабильности — из-за особенностей работы платежного шлюза на тестовом окружении, платёжная карта привязывалась не всегда, поэтому примерно в двух раз из десяти тесты завершались с ошибкой.
С помощью Backend Client мы можем обойти этот фактор, и напрямую «навесить» подписку на нужного пользователя, минуя платежный шлюз. Получаем стабильный результат выполнения теста — 0 падений из 100 возможных.
Планы развития
Тесты на PROD
Логичным решением по поводу дальнейшего развития является вывод как тестов, так и описанного инструментария в продакшн-окружение.
Плюсы очевидны — гоняя автотесты на проде, мы точно можем быть уверены, что конечный пользователь будет максимально защищен от возможных критичных багов, блокирующих пользовательские сценарии.
Статистика и аналитика
В больших проектах такая вещь, как отправка статистики, является бизнес-критичной функцией — ведь именно от неё зависит наличие всей той обратной связи, позволяющей понимать, в какую сторону в дальнейшем развивать продукт. Пока что, к сожалению, это смотрится руками, но в планах мы собираемся использовать Backend client и для автоматических проверок отправляемых данных приложением. Начнём с самого критичного — отправки аналитики при просмотре контента в плеере, постепенно двигаясь в сторону расширения.
Внедряйте похожие штуки и в своих проектах, и стабильных вам автотестов!