Как я разрушил свои стереотипы об автотестах, или Мой путь от Appium до Kaspresso

в 12:03, , рубрики: android, espresso, kaspresso, open source, testing, ui testing, автоматизация тестирования, автотесты, тестирование, Тестирование мобильных приложений

Всем привет!

Меня зовут Сергей Дударев, я руководитель направления автоматизированных тестов в департаменте мобильной разработки «Лаборатории Касперского». В этой статье хочу рассказать, как я прошел путь от Appium до open-source-фреймворка Kaspresso, с чего начинал, какие делал для себя открытия, как разрушались мои стереотипы и какие по итогу были сделаны выводы.

Как я разрушил свои стереотипы об автотестах, или Мой путь от Appium до Kaspresso - 1

Как пришел к выбору Appium

Когда я перешел в мобильное тестирование, передо мной встал выбор инструмента для автоматизации. Выбирал я между нативными инструментами (Espresso, Kaspresso) и Appium.

На тот момент про Kaspresso было мало информации, из того, что попадалось на просторах Интернета, — это README.md на github и несколько статей, в которых не было достаточно информации, чтобы понять все его возможности.

Из вариантов у меня остались Espresso и Appium.

Последний был более популярен среди моих коллег из соседних команд.

Пообщавшись с ними по поводу их выбора и изучив несколько сравнительных статей Appium с Espresso, я выделил для себя следующие преимущества в пользу Appium:

  1. Appium предполагает меньший порог вхождения по сравнению с нативными инструментами. Получается, что ручным тестировщикам без опыта в написании кода будет проще написать свой первый тест, который начнет приносить пользу, — а значит, интерес к автоматизации будет расти. Я не раз встречал ручных тестировщиков, которые теряли такой интерес, потому что не могли разобраться в сложном проекте и написать свой первый тест. Также я встречал тех, кто начинал писать автотесты в проектах с продуманной архитектурой, составляя свои первые тесты как конструктор из готовых шагов, — интерес у них только нарастал, и они все больше углублялись в автоматизацию, доходя до уровня автоматизатора тестирования. Поэтому чем меньше порог вхождения, тем лучше.

  2. С помощью Appium можно взаимодействовать со сторонними приложениями. В Espresso, например, такой возможности нет. У Android для этого есть отдельный инструмент UIAutomator, но хотелось иметь схожий api по работе как со своим приложением, так и со сторонним. Конкретно это преимущество было ключевым для меня, поскольку специфика проекта подразумевает множество взаимодействий со сторонними приложениями, да и с самой системой Аndroid.

  3. С помощью Appium можно написать один тест для двух платформ сразу (Android и iOS), в отличие от нативных инструментов. Тоже значимый аргумент в пользу appium, ведь выглядит так, будто мы можем решить две задачи одним инструментом.

Так мой выбор пал на стек из python + pytest + appium.

Время экспериментов

На протяжении примерно полугода я автоматизировал тесты, используя этот стек, и вроде бы все шло хорошо, но у меня все больше проявлялся интерес к Kasprеsso — о нем стало появляться все больше информации и лестных отзывов, а также появился туториал, который пошагово объяснял возможности фреймворка.

На тот момент у меня не было понимания, насколько он подходит именно мне, поскольку у проекта есть своя специфика. Я решил написать несколько тестов на Kasprеsso, так сказать, факультативно, без ущерба для автоматизации своего проекта.

Как разрушались мои стереотипы

Взяв у коллег ссылку на туториал по Kaspresso, я начал с ним знакомство, параллельно внедряя фреймворк в свой проект. Оказалось, что это совсем не сложно! Достаточно добавить несколько зависимостей и создать пакет с тестами. Об этом подробно написано в секции интеграции.

Написать первый тест оказалось тоже совсем несложно благодаря понятному и лаконичному Kotlin DSL. Если посмотреть на код теста, становится сразу понятно, что на экране WizardAgreements нажимаем кнопку «Далее», а затем на экране запроса разрешения проверяем, что видна эта кнопка:

@Test
fun requiredPermissionTest() =
   run {
       step("Agreement Screen") {
           WizardAgreementsScreen {
               continueButton {
                   click()
               }
           }
       }
       step("Required permission screen") {
           RequiredPermissionScreen {
               continueButton {
                   isVisible()
               }
           }
       }
   }

Когда я написал первый тест, был разрушен мой первый стереотип про порог вхождения. Долгое время я был уверен: чтобы написать нативный тест, нужно погрузиться в kotlin (c которым я практически не был знаком), глубоко понимать структуру тестируемого приложения. На самом же деле начать писать автотесты на Kaspresso не сложнее, чем на Appium, а как по мне — так и вовсе проще. Убедиться в этом вы сможете сами, пройдя уроки в туториал по Kaspresso.

Когда дело дошло до взаимодействия со сторонними приложениями, разрушился мой второй стереотип. Я считал, что нативные инструменты не подходят для этих задач, но, как оказалось, это правдиво только для Espresso. Если мы хотим тестировать с его помощью, то для взаимодействия с другими приложениями стоит взять другой фреймворк — UIAutomator. Однако Kaspresso создан на основе этих двух инструментов и предоставляет удобные и функциональные обертки над ними. Таким образом, вам не нужно использовать что-либо еще — этот фреймворк закрывает все потребности. Кроме того, мы получаем единый стиль в наших тестах при взаимодействии как со своим приложением, так и со сторонними.

 В Appium также используется UIAutomator как один из вариантов взаимодействия с приложениями.

Не менее дискуссионной остается и возможность написать один тест для iOS и Android с помощью Appium. С одной стороны, это действительно так: можно написать один тест на одном языке, который будет запускаться на двух платформах, но по факту два приложения зачастую имеют разный UX и UI (ввиду не только неконсистентности дизайна, но и различий в OS) и различные локаторы для элементов. В итоге вместо единого кода для двух платформ мы получаем много if-ов в коде теста для разделения логики по платформам, из-за чего тест будет громоздким и неудобным в отладке.

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

Дальше — больше

Чем дальше я углублялся в изучение возможностей Kaspresso, тем больше проникался симпатией к нему. Первое, что приходит в голову, — продуманная архитектура тестов. Она основывается на паттерне page object. При написании тестов не нужно продумывать основу их архитектуры, достаточно следовать концепции, заложенной в Kaspresso. Следующее — Kaspresso из коробки предоставляет то, что в своем проекте с Appium мне приходилось придумывать и реализовывать самому. Например:

1. adb

Для взаимодействия с adb-сервером в проекте с Appium мне приходилось писать свою реализацию, которая выполняет adb-команды через python‑библиотеку subprocess. В Kaspresso же достаточно обратиться к интерфейсу adbServer, вызвать метод performShell, который выполняет команды shell в adb (не нужно писать команду целиком, достаточно написать все, что идет после shell), передать в метод команду, которую мы хотим выполнить:

adbServer.performShell("pm list packages")

В ответ получим результат выполнения этой команды.

Еще у adbServer есть методы performAdb, который выполняет команды adb (туда передаем все, что в команде идет после adb), и performCmd — выполняет команды командной строки на хосте, с которого были запущены тесты.

В Espresso же вовсе нет возможности взаимодействовать с adb.

2. Обертки adb-команд

Готовые обертки adb-команд экономят время на поиски того, как эти самые команды составлять. Более того, они избавляют от необходимости реализовывать выполняющие эти adb-команды методы у себя в проекте. Например, чтобы отключить Интернет на устройстве, достаточно вызвать:

device.network.disable()

Нет необходимости знать и выполнять отдельно команды «adb shell svc wifi disable» и «adb shell svc data disable». Также класс Devices имеет большой набор методов для взаимодействия с OS Android: например, можно эмулировать входящие звонки и СМС, устанавливать и удалять приложения, изменять язык. Со всеми другими возможностями класса Devices можно ознакомиться здесь.

3. Автоскролл

В Kaspresso реализован скролл до элемента, с которым мы собираемся взаимодействовать. Этот механизм позволяет не задумываться о том, что на некоторых экранах элемент может не уместиться и быть за его границами. В случае необходимости Kaspresso сам проскроллит до нужного элемента. Это делает тесты стабильнее и ускоряет их написание, ведь теперь нет необходимости реализовывать метод скролла у себя в проекте — а затем еще отдельно продумывать, где добавить его вызов, прежде чем кликать по нему, например.

4. Работа с пермишенами

Есть несколько способов выдачи разрешений, которые поддерживает Kaspresso. Первый — автоматический, при установке приложения, второй — при использовании пользовательского сценария, через UI. Здесь стоит остановиться на втором варианте. В случае с Appium, если у нас стоит задача проверить запрос и применение пермишена, нам нужно найти подходящий для него локатор и написать метод, который будет искать и принимать его на странице.
В случае с Kaspresso нам достаточно вызвать уже реализованный метод, который проверит наличие диалога и пример пермишена при его наличии:

device.permissions.apply {
   flakySafely {
       Assert.assertTrue(isDialogVisible())
       allowViaDialog()
   }
}

5. Скриншоты

Наше приложение должно поддерживать множество локализаций, поэтому есть важная потребность просматривать, как выглядят экраны приложения на разных языках. Для решения этой задачи, а также для проведения design review Kaspresso предоставляет очередное готовое решение из коробки. Только посмотрите, как мало нужно написать кода, чтобы снять скриншоты с экрана приложения на 12 языках и сохранить их в папке sdcard/Documents/screenshots/:

WizardAgreementsScreen {
   continueButton {
       isVisible()
       captureScreenshot("AgreementScreen")
   }
}

Снимать скриншоты с экрана можно с помощью двух вариантов. Первый – проходя весь пользовательский сценарий вплоть до нужного экрана. Второй -- когда мы не запускаем всё приложение, а стартуем только отдельные фрагменты – это позволяет делать скриншоты быстро и стабильно. Подробно об этом можно почитать здесь. Помимо самих скриншотов, будут сохранены xml файлы с указанием всех строк на экране и их id.

6. Работа с logcat

Есть тесты, в которых недостаточно взаимодействия с UI, ведь часть логики может быть спрятана от пользователя, и для проверки того, что наше приложение отрабатывает так, как мы от него ожидаем, нам нужно обращаться к логам через logcat. Kaspresso и здесь предоставляет нам готовое решение — чтобы найти интересующую строку в логе, достаточно сделать:

device.logcat.readLogcatRows(includePattern = "some string")

7. Steps

Каspresso позволяет делать автотесты более читаемыми благодаря выделению кусков кода в отдельные блоки, которые соответствуют тест-кейсам, а еще добавляет логирование и скриншоты в тесты. Подробнее о steps можно почитать здесь.

8. Защита от флаков

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

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

Также хотелось бы немного поговорить о, возможно, неочевидном преимуществе нативных инструментов — тесты находятся в одном проекте с тестируемым приложением. Это расширяет наши возможности, позволяя тестировать приложение как white box, что добавляет стабильности тестам и расширяет возможности.

Получается, что Kaspresso…

это фреймворк, с помощью которого каждый желающий сможет начать писать автотесты для Android-приложений, так как порог вхождения у него совсем невысокий. Мои стереотипы относительно нативных инструментов автоматизации были разрушены, ведь большинство из них относились к Espresso. Kaspresso может закрыть все потребности в тестировании Android-приложений.

Если Kaspresso сравнивать с Appium, то в своих возможностях он мало того что не уступает Appium, так еще и во многом превосходит его! Поэтому если вы тоже хотите пробовать новые инструменты и разрушать стереотипы о тестировании и не только — присоединяйтесь к «Лаборатории Касперского»! А чтобы больше узнать о работе с Kaspresso, скорее вступайте в наш чат поддержки. Это большое сообщество c более чем тысячью участников, где есть вся самая полезная информация по работе с фреймворком.

Автор: sdudarev

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js