Как я перестал бояться и полюбил автоматизацию мобильных приложений — Robot Framework
Часто автотестирование кажется новичкам чем-то невероятно сложным и недостижимым. Многие думают, что для того, чтобы начать писать автотесты, необходимо сначала получить глубокие знания в программировании, разобраться во всех технических тонкостях ручного тестирования и только лишь потом пробовать писать автоматизированные тесты.
Это, конечно, не так. Я предлагаю вам познакомиться с Robot Framework — инструментом, который позволит писать автотесты, даже если у вас не было никакого опыта программирования.
Эта статья — адаптация моего видеотуториала. Если в формате видео вам проще воспринимать информацию — велком!
Начнем с демонстрации
Давайте сразу посмотрим пример автотеста, написанного с использованием Robot Framework:
*** Settings *** Test Setup auth_reg.Precondition: User At Auth Form Test Teardown android.Quit App Test Timeout 2m *** Variables *** $ test@test.ru $ 123 *** Test Cases *** Standard Authorization [Documentation] Процесс авторизации через логин и пароль [Tags] android authorization Fill Both Fields Incorrectly Page Should Not Contain Element $ Fill One Field Incorrectly Page Should Not Contain Element $ Input Correct Data Wait Until Element Is Visible $ *** Keywords *** Fill One Field Incorrectly [Documentation] Заполняем одно из полей (email или пароль) некорректно Input Text $ $ Input Password $ $ Click Element $
Сразу заметно отсутствие того, чем пугает нас программирование, — классов, методов и сложных синтаксических конструкций. Вместо этого — простые и понятные английские слова, знакомые любому тестировщику, который знает хотя бы основы теории тестирования.
То, что отмечено звёздочками с обеих сторон, — это блоки теста.
Блок Settings
Это настройки теста. Они могут быть разные, но тут используются три:
- Test Setup — это предусловие . У нас оно звучит как «пользователь находится на экране формы авторизации».
- Test Teardown — это постусловие . У нас это закрытие приложения.
- Test Timeout — время, за которое тест должен завершиться. Если не успеет, то кейсу поставится статус Failed.
Блок Variables
В этом блоке мы можем создавать переменные. Сюда мы часто выносим либо локаторы, либо, например, тестовые данные — у нас здесь несуществующий E-mail и неправильный пароль.
Название переменной пишется со знаком доллара и внутри скобок — например, $ . Большими буквами, потому что так принято писать глобальные переменные (работающие на весь тест или несколько тестов).
Блок Test Cases
Test Cases — сами тесты. У нас в этом блоке один тест, который проверяет стандартную авторизацию.
Внутри теста мы видим так называемые «кейворды» — функции, которые предоставляет сам фреймворк, а также те, которые создаём мы. Часто мы воспринимаем кейворды как шаги воспроизведения. Так, например, Fill Both Fields Incorrectly — это шаг ручного теста, который звучит как «Заполнить оба поля некорректными данными». Еще есть кейворды Fill One Field Incorrectly и Input Correct Data — в них мы проверяем некорректное заполнение одного поля и ввод существующих данных соответственно.
После каждого шага мы видим Page Should Not Contain Element и Wait Until Element Is Visible — это встроенные кейворды, позволяющие нам проверить наличие или отсутствие элементов на странице. Так, в одном случае мы проверяем, что на странице не появилось имя пользователя (если авторизоваться не получилось), а в другом — дожидаемся имени пользователя (если мы всё-таки авторизовались).
Блок Keywords
Это то самое место, где мы расписываем логику конкретного шага или набора действий. Если говорить языком традиционного программирования, то это — функции (или методы).
В демонстрационном кейворде Fill One Field Incorrectly мы вводим имя пользователя в одно поле, пароль — в другое, и потом кликаем на кнопку «Войти».
И это работает?
Да! После написания такого теста всё, что остаётся сделать, — это запустить одну команду в терминале для запуска теста (или просто нажать на кнопку запуска в интерфейсе вашей IDE ). После этого тест запустится на вашем реальном девайсе или эмуляторе — при условии, что вы их настроили, конечно.
Сразу отмечу, что Robot Framework не просто хобби‑игрушка. Этот инструмент мы активно используем в проектах Рамблера — в частности, в сервисах Афиши — одного из крупнейших агрегаторов событий в стране. Пора официально представиться. Я — Никита, автоматизатор тестирования в Rambler&Co, наставник на курсе «Инженер по тестированию» в Яндекс Практикуме и основатель Брейни QA.
Уговорил, давай попробуем!
Чтобы начать, нам необходимо сделать две вещи:
- Установить инструменты, необходимые для работы Robot Framework и мобильной автоматизации.
- Выбрать и установить среду разработки (IDE)
Об установке инструментов
Скачать и установить нужно будет следующее:
- Java JDK — для корректной работы инструмента автоматизации и среды разработки приложений на Android
- Android Studio — для установки вспомогательных пакетов Android и работы с эмуляторами
- NodeJS — для установки инструмента автоматизации через его встроенный менеджер пакетов
- Homebrew — для более простой установки NodeJS на Mac
- Appium — для непосредственной автоматизации тестирования
Чтобы не терять время и не растягивать статью инструкцией по установке (которая, впрочем, сильно разнится в зависимости от операционной системы), я просто приложу туториалы из публичного доступа:
- Установка и настройка на Mac
- Установка и настройка на Windows
Эти уроки я рекомендую посмотреть, потому что в процессе происходит довольно много действий (настройка переменных окружения, загрузка пакетов, установка зависимостей и пр.), в которых можно запутаться, поэтому лучше будет идти по шагам.
Об установке IDE
Среду разработки обычно рекомендую выбирать исключительно по предпочтениям, но советовал бы остановить выбор на одной из этих двух:
У каждой из них есть плагины (расширения), поддерживающие функционал нашего с вами инструмента. На момент написания статьи рекомендую RobotCode для VSCode и Language Server для PyCharm.
Если вы ранее не работали с этими средами разработки, выбирайте ту, которая больше нравится. Я, например, использую VSCode, потому что эта IDE — как швейцарский нож в мире разработки.
Создание проекта
На данном этапе для нас главное — создать проект с виртуальным окружением Python. В PyCharm при первом открытии нам предложат создать проект, и если мы согласимся, то виртуальное окружение нам создадут автоматически. Ничего в настройках менять не нужно, можно оставить как есть..
Далее нам нужно уже в проекте создать файлик requirements.txt, где будут указаны зависимости для скачивания. Их можно просто записать так:
robotframework robotframework-appiumlibrary
Первое — сам Robot Framework, второе — библиотека Appium, которая как раз таки и позволяет проводить мобильные тесты. На её основе, кстати, сейчас работает большинство ненативных проектов автоматизации мобильного тестирования.
PyCharm предложит эти зависимости установить, если не предлагает — открываем встроенный терминал и пишем pip3 install. С этого момента можно уже начинать писать тесты.
В случае с Visual Studio Code процесс немного отличается. При старте нового проекта я обычно делаю так:
- Создаю папку в файловой системе
- Открываю эту папку через VS Code
- Создаю файлик requirements.txt и вписываю то, что написано выше.
- Нажимаю Ctrl (Cmd) + Shift + P и в выпадающем меню набираю “Python: Create Environment”. Сначала выбираем виртуальное окружение (venv), затем файлик, из которого возьмутся зависимости (мы его создали в шаге 3).
Если всё сделано правильно, то зависимости установятся вместе с виртуальным окружением, что также открывает нам дорогу к написанию нашего первого теста.
Пишем первый автотест
Прежде чем начать писать тест в Robot Framework, нужно создать файл для него. Мы можем назвать его как угодно — я назову, например, first_test. Главное — прописать правильное расширение файла — это .robot
Итак, как я уже писал ранее, самое важное происходит в специальных блоках. Создадим блок Settings, выделив его тремя звездочками (***) с каждой из сторон. В нём мы подключаем библиотеки и ресурсы, а также устанавливаем предусловия и постусловия.
На первом этапе нам нужно подключить библиотеку, для этого пишем Library, ставим таб (отступы в Robot Framework, как и в Python, используются не только для декорации, но и для правильного выполнения теста) и пишем название — AppiumLibrary.
*** Settings *** Library AppiumLibrary
Следующий блок называется Test Cases, и он отвечает за тест-кейсы.
Чтобы создать тест-кейс, под объявлением блока мы пишем его название — First Test.
В этом автотесте мы выполним три простых действия:
- Открыть приложение
- Подождать 5 секунд
- Закрыть приложение
За действия в Robot Framework отвечают кейворды, или, говоря языком традиционного программирования, функции. Какую-то часть функций предоставляет сам Robot Framework, какую-то — его библиотеки, а какую-то придётся писать нам самим.
К счастью для нас, документация по кейвордам у «робота» есть, и она достаточно понятна и хорошо написана. Для начала нам хватит вот этих ссылок:
- Документация по встроенным (BuiltIn) кейвордам
- Документация по библиотеке для мобильных автотестов (AppiumLibrary)
Нам нужно открыть приложение. Что нужно делать, когда не знаем, какой кейворд нам нужен? Правильно, идём в документацию!
Если перейдём по второй и в поиске наберём магическое «Open«, то найдём кейворд Open Application:
Здесь мы видим аргументы, которые кейворд принимает (remote url, alias, strict_ssl), — это то, что мы пишем, разделяя табами. Ниже — пример использования, где видим remote_url во втором столбике, а в третьем — alias. Всё, что пишется дальше, это так называемые capabilities — параметры сети, устройства и приложения, которое хотим запустить. Их сюда можно написать много разных, но я расскажу о самых основных, которых хватит для почти любого проекта:
- remote_url — это адрес сервера. Сервер мы будем включать на нашем компьютере, поэтому нам нужно ввести локальный адрес и порт — для всех компьютеров он будет такой — http://127.0.0.1:4723
- automationName — это драйвер для прогона тестов — тот, который будет нажимать кнопки, делать свайпы, скроллы и прочие подобные штуки. Самый популярный для Android — это UiAutomator2
- platformName — это название операционной системы устройства — Android
- platformVersion — версия операционной системы. Чтобы её узнать, на телефоне переходим в Настройки — О телефоне.
- deviceName — название устройства. Оно тоже пишется и настраивается там же, где и версия ОС.
- udid — это id устройства. Чтобы его узнать, нужно перейти в терминал вашего компьютера и ввести команду adb devices. Если команда не распознана, вам нужно установить и настроить adb (но если вы шли по шагам из уроков установки, то у вас оно уже будет). Если у вас есть подключённые по USB устройства (или активные эмуляторы), то вы увидите id там.
- appPackage — это ID приложения. Я использую Афишу — агрегатор событий с возможностью купить билеты. Чтобы узнать его ID, нам нужно перейти в Настройки — Приложения, затем найти приложение и нажать на иконку информации. Имя пакета — это то, что нам нужно.
- appActivity — это активность, которую нужно запустить. Суть в том, что в Android мы не просто запускаем приложение — мы запускаем конкретную активность с конкретным айди. На реальном проекте название активности можно уточнить у разработчиков либо найти самому с помощью приложений вроде apk info или с помощью специальных консольных команд.
Теперь это нужно записать в код. У меня получилось вот так:
*** Test Cases *** First Test Open Application remote_url=http://127.0.0.1:4723 . automationName=UiAutomator2 . platformName=Android . platformVersion=13 . deviceName=POCO . udid=6c01a765 . appPackage=ru.afisha.android . appActivity=ru.afishaog.android.presentation.app.AppActivity
Обратите внимание на то, как мы задаём значения свойств. Сначала вводим название, затем знак «равно» — и значение. Чтобы это всё лучше читалось, можно переносить строки. Для этого нужно проследить, чтобы перед строкой были . (три точки) — это означает «мы продолжаем предыдущую строку и переносим текст для лучшей читаемости».
Уже на этом этапе мы можем запустить тест, но перед этим мы должны запустить сервер Аппиума. Это просто: переходите в терминал на вашем устройстве и пишете команду appium. Если у вас показывает нечто подобное, то всё сделано правильно:
Далее, у вас установлен один из рекомендуемых плагинов, то можно просто нажать на зеленую стрелочку возле теста:
После этого на вашем девайсе вы увидите, как откроется приложение, а в терминале в IDE напишут, что тест прошёл успешно:
На ранних этапах могут возникать разные ошибки (adb не работает, appium не открылся, телефон не настроен, приложение не запустилось), но, к счастью, когда один раз настроишь процесс, дальше такие проблемы уже не беспокоят. Если вы чётко следовали инструкциям, но у вас появилась ошибка, которую не можете решить, — приходите в комментарии, посмотрим, что с этим можно сделать 🙂
Кстати, в Robot Framework уже встроены отчёты, которые создаются после каждого прогона:
А если есть необходимость погрузиться в процесс прогона с максимальной детализацией всего, что произошло, помогут логи:
Но вернемся к нашему тесту, который выглядит так:
Открыть приложение- Подождать 5 секунд
- Закрыть приложение
Чтобы подождать какое-то время, мы можем использовать кейворд Sleep. В него нужно передать время ожидания — у нас это пять секунд.
После того как мы подождали нужное время, нам нужно закрыть приложение. Подходящий кейворд можно найти — это Close Application.
Наш тест теперь выглядит так:
*** Test Cases *** First Test Open Application remote_url=http://127.0.0.1:4723 . automationName=UiAutomator2 . platformName=Android . platformVersion=13 . deviceName=POCO . udid=6c01a765 . appPackage=ru.afisha.android . appActivity=ru.afishaog.android.presentation.app.AppActivity Sleep 5s Close Application
Чтобы сделать код красивее и проще, мы можем сделать две вещи:
- Внедрить переменные
- Перенести Open Application в отдельный кейворд
Работа с переменными
Программирование очень не любит «magic numbers/strings/etc». Это значит, что по возможности каждое число или строчка, которые мы передаём в код, должны выноситься в отдельные переменные.
Здесь нам стоит вынести все свойства в отдельные переменные. В этом нам поможет блок Variables:
*** Variables *** # Название устройства $ POCO # Идентификатор устройства $ 6c01a765 # Используемая платформа $ Android # Версия платформы $ 13 # Компания устройства $ "XIAOMI" # Automation Name $ UiAutomator2 # Connection $ http://127.0.0.1:4723 # Ссылка на приложение $ ru.afisha.android # Ссылка на активность приложения $ ru.afishaog.android.presentation.app.AppActivity *** Test Cases *** First Test Open Application remote_url=$ . automationName=$ . platformName=$ . platformVersion=$ . deviceName=$ . udid=$ . appPackage=$ . appActivity=$ Sleep 5s Close Application
Тут мы видим, как пишутся переменные — $ . Значения передаются через таб. То, что начинается с #, — это комментарии, которые нужны для удобства разработчика и понимания того, что это за переменные. Комментарии при выполнении кода игнорируются, они нужны только для вас.
Создание кейвордов
В целях демонстрации мы можем вынести Open Application со всеми его свойствами в отдельный кейворд в блоке Keywords и назвать его, например, Open App. Всё, что нужно сделать:
- Создать блок Keywords
- Создать (инициализировать) новый кейворд
- Перенести нужные функции в только что созданный кейворд
- Заменить функции в тесте на название кейворда
Должно получиться вот так:
*** Test Cases *** First Test Open App Sleep 5s Close Application *** Keywords *** Open App Open Application remote_url=$ . automationName=$ . platformName=$ . platformVersion=$ . deviceName=$ . udid=$ . appPackage=$ . appActivity=$
Такой подход не только помогает нам добиться удобства читаемости кода, но и помогает с его поддержкой. Если мы, например, хотим при старте приложения делать какое-нибудь ещё действие, то можем это действие поместить в Open App, и его не придётся каждый раз прописывать заново. Один раз вызвал кейворд и пользуешься.
А теперь — настоящий автотест!
Давайте напишем что-нибудь посерьезнее, например, автотест на реальный сценарий, который проверяется в нашем продукте.
У нашего приложения есть онбординг — стартовые экраны, которые помогают пользователю сориентироваться в приложении, параллельно запрашивая важные для работы доступы.
Один из экранов выглядит вот так:
И, соответственно, у нас есть тесты, онбординг проверяющие. Предположим, есть такой:
Заголовок: Онбординг с разрешением геолокации и подтверждением предлагаемого города
Предусловие: приложение открыто
Шаги:
- Разрешить геолокацию
- Подтвердить предлагаемый город
- Разрешить уведомления
Такой тест в Robot Framework может выглядеть так:
*** Settings *** Resource onboarding.resource *** Test Cases *** Allow Location And Confirm Town [Documentation] Онбординг с разрешением геолокации и подтверждением выбранного города launcher.Open App onboarding.Allow Location onboarding.Confirm Town onboarding.Allow Notifications Wait Until Element Is Visible ru.afishaog.android:id/itemTileEventIv
Здесь мы видим, что тест очень короткий, потому что всё необходимое мы вынесли в отдельные ресурсные файлы. В Robot Framework такие файлы обладают расширением .resource, и именно такой файл мы подключаем в блоке Settings.
А теперь давайте заглянем в этот файл:
*** Settings *** Resource ../common.resource *** Keywords *** Allow Location [Documentation] Разрешить приложению использовать геолокацию Wait Until Element Is Visible ru.afishaog.android:id/fragOnboardinSubmitBtn Click Element ru.afishaog.android:id/fragOnboardinSubmitBtn Wait Until Element Is Visible com.android.permissioncontroller:id/permission_allow_foreground_only_button Click Element com.android.permissioncontroller:id/permission_allow_foreground_only_button Confirm Town [Documentation] Подтвердить предлагаемый системой город Wait Until Element Is Visible timeout=10 Click Element Notifications [Documentation] Разрешить уведомления Wait Until Page Contains Element ru.afishaog.android:id/fragOnboardinSubmitBtn Click Element ru.afishaog.android:id/fragOnboardinSubmitBtn Wait Until Page Contains Element com.android.permissioncontroller:id/permission_allow_button Click Element com.android.permissioncontroller:id/permission_allow_button
Здесь видим, что в этом файле мы подключаем ещё один ресурс — common, который может подключать другие дополнительные ресурсы. Именно там мы подключили другой ресурсный файл (launcher.resource), отвечающий за открытие приложения.
Как вы видите, в ресурсном файле нет тест-кейсов — только кейворды, причем с такими же названиями, как и в тесте выше. Да, мы прописываем их логику здесь, а вызываем там. Это помогает избежать повторения одного и того же кода между тестами, а также упрощает процесс поддержки (если что-то сломалось — можно поправить только в одном месте).
Каждый кейворд задокументирован, и легко понять, что именно происходит: в одном мы разрешаем геолокацию, в другом — подтверждаем город, в третьем — разрешаем уведомления.
Здесь используются два новых кейворда, которые предоставляются библиотекой AppiumLibrary:
- Wait Until Element Is Visible — дождаться, пока нужный элемент станет видимым
- Click Element — кликнуть на элемент
Этот тест на самом деле очень простой — он просто ждёт элементы и кликает по ним.
Вы спросите: а как нам найти элементы, которые ждёт и прокликивает робот? А для этого мы используем программу Appium Inspector. Её интерфейс выглядит так:
Инструмент довольно простой. Он подключается к нашему девайсу и делает интерактивный скриншот. Мы можем нажимать на разные части этого скриншота и находить идентификаторы элементов — это именно то, что мы вписываем справа от Wait Until Element Is Visible и Click Element. Подробнее про Appium Inspector можно найти, например, в этом видео.
По сути, когда мы пишем автотест в Robot Framework, наша работа чрезвычайно проста:
- Взять ручной тест
- С помощью Appium Inspector найти все элементы, с которыми нужно взаимодействовать
- Выбрать подходящие кейворды (чему помогает документация или личный опыт)
- Вписать кейворды в тест с использованием локаторов из шага 2
Вот такой простой алгоритм на самом деле.
Дорабатываем тест
В первую очередь непонятные локаторы нужно поместить в понятные переменные, чтобы кейворды в ресурсном файле выглядели так:
*** Keywords *** Allow Location [Documentation] Разрешить приложению использовать геолокацию Wait Until Element Is Visible $ Click Element $ Wait Until Element Is Visible $ Click Element $ Confirm Town [Documentation] Подтвердить предлагаемый системой город Wait Until Element Is Visible $ timeout=10 Click Element $ Allow Notifications [Documentation] Разрешить уведомления Wait Until Page Contains Element $ Click Element $ Wait Until Page Contains Element $ Click Element $
Сами переменные с локаторами выносим в отдельный ресурсный файл:
*** Settings *** Documentation Блок для локаторов онбординга *** Variables *** $ ru.afishaog.android:id/fragOnboardinSubmitBtn $ com.android.permissioncontroller:id/permission_allow_foreground_only_button $ com.android.permissioncontroller:id/permission_allow_button
Запуск приложения и его закрытие лучше вынести в отдельные кейворды и пометить их как Test Setup (предусловие) и Test Teardown (постусловие) соответственно:
*** Settings *** Resource onboarding.resource Test Setup common.Launch App Test Teardown common.Close App *** Test Cases *** Allow Location And Confirm Town [Documentation] Онбординг с разрешением геолокации и подтверждением выбранного города onboarding.Allow Location onboarding.Confirm Town onboarding.Allow Notifications Wait Until Element Is Visible $
А еще можно разветвить код с использованием условных операторов. Дело в том, что экран с разрешением уведомлений показывается только в случае, если у пользователя Android версии 13 и выше. В таком случае, тест будет выглядеть так:
*** Test Cases *** Allow Location And Confirm Town [Documentation] Онбординг с разрешением геолокации и подтверждением выбранного города onboarding.Allow Location onboarding.Confirm Town IF $ >= 13 onboarding.Allow Notifications Wait Until Element Is Visible $
С помощью конструкции IF $ >= 13 onboarding.Allow Notifications мы говорим программе действовать так — «Если версия операционной системы выше 13-й, добавь новый шаг с разрешением уведомлений».
В итоге у нас получился готовый автотест, который уже прямо сейчас может сократить время регрессионного тестирования. Чем больше таких тестов автоматизировано — тем проще жизнь тестировщика.
Что еще умеет Robot Framework с AppiumLibrary?
Практически всё! Если говорить о мобильном тестировании, то он позволяет работать:
- с переменными
- с предусловиями и постусловиями
- с условными операторами (IF, ELSE, ELSE IF), где нужно разветвление кода в зависимости от условий
- с циклами (WHILE, FOR), где определённые части кода нужно повторять несколько раз
- с вводом текста (заполнение полей)
- с жестовой навигацией (скроллы, свайпы, зумы — всё поддерживается)
- с манипуляциями приложением (закрыть, отправить в фон, перезапустить, переключить на другое)
- со многими другими сценариями
Фактически этим инструментом можно покрыть практически любые ручные сценарии тестирования. Напомню, что этот инструмент активно используется в большом количестве компаний (в том числе и на российском рынке, например, в нашем Рамблере).
Стоит отметить, что Robot Framework действительно не является стандартом индустрии автоматизации тестирования, и на мой взгляд — очень зря.
Как вам инструмент?
Если он понравился — я очень рад!
Вы уже прямо сейчас можете использовать Robot Framework в своей работе — автоматизировать тесты, которые вам не нравится проходить вручную. Если сейчас такой необходимости нет — в качестве практики перед полноценным погружением в мир автотестов.
Надеюсь, вместе мы сможем популяризировать «робота» и помочь IT‑компаниям понять, что автоматизация — это не только не дорого, не сложно и не страшно, но иногда даже и приятно!
- тестирование
- Robot Framework
- автотесты
- автотестирование
- автоматизация
- мобильное тестирование
- Блог компании Яндекс Практикум
- Тестирование IT-систем
- Тестирование мобильных приложений
- Учебный процесс в IT
https://habr.com/ru/companies/yandex_praktikum/articles/794064/