Всем привет! Вас приветствуют Игорь Харитонов и Иван Селиванов — уже более 2,5 лет мы трудимся вместе на должности QA-инженеров в проекте XtremIO Management Server (XMS) компании Dell Technologies. Сегодня мы хотим поделиться полным процессом организации и автоматизации тестирования WebUI-части с нуля, поскольку не нашли на просторах Интернета подробного описания процесса автоматизации и хорошего решения для настройки окружения под UI-автотесты.
Если говорить вкратце о том, что такое XMS, то это сервер управления высоконагруженными системами хранения данных (СХД на твердотельных носителях — иными словами, кластер/массив, состоящий из SSD-накопителей). Управление массивом в нашем случае осуществляется с помощью REST API запросов и команд в CLI (Command Line Interface), а также при помощи пользовательского графического интерфейса (GUI). Чтобы примерно понять масштабы тестирования в нашем проекте, попробуйте представить себе огромную лабораторию с невероятным количеством железа и тысячами подсоединённых к нему проводов. К такому серверу можно подключать огромное количество разнообразных плагинов из экосистемы для управления СХД извне и наоборот. А теперь представьте, что каждый элемент этого сервера требует тестирования руками. На рисунке 1, который представлен ниже, вы видите одну из многих страниц нашего UI. На первый взгляд может показаться, что здесь и тестировать нечего, но это только вершина айсберга.
Рисунок 1. Пример UI-страницы из раздела «Безопасность данных» с запущенными собственными сеансами репликации (Native Replication).
Более подробно о Native Replication можно узнать из видео по ссылке.
Ручных тестов на UI чуть больше 3000, и к ним постоянно добавляются новые после очередных доработок продукта. Все наши основные UI-тесты делятся на Display (тесты на отображение всего и вся на страницах сервера; это тесты с самым высоким приоритетом), Display Functionality (тесты на функциональность отображения элементов страницы) со средним приоритетом и Functionality (тесты на функциональность элементов страницы). Последние не менее важны, но идут у нас с низким приоритетом, так как функциональность продукта проверяется нашими коллегами, которые тестируют REST и CLI. Наши тесты мы храним, гоняем и отмечаем в ALM Quality Center от Micro Focus. Это довольно непривычная, но удобная система контроля качества всего процесса тестирования.
На разных циклах тестирования, по нескольку раз в неделю, отдел разработки выпускает новые сборки версий будущего релиза с доработками и исправлениями уже найденных ошибок. Это ещё больше усложняет процесс ручного тестирования, ведь всё, что уже было проверено, могут «сломать» в следующих сборках. Приходится перепроверять каждую версию, чтобы избежать появления сюрпризов, когда продукт уйдёт к серьезным клиентам.
В итоге огромное количество тестов и вся эта ручная и сложная рутинная работа подвигли нас заняться автоматизацией нашего UI. Задача стояла непростая, зато интересная.
Рассмотрим подробнее структуру нашей автоматизации. С самого начала мы выбирали между Selenium Grid Hub версий 3 и 4 Alpha, а также присматривались к Selenoid и его более красивому UI-интерфейсу для отладки тестов. Selenoid — это сервер, который при использовании того же Selenium веб-драйвера позволяет запускать браузеры в Docker-контейнерах.
Наверное, многие уже знают, что настройка Selenium Grid на хабах и нодах отнимает очень много времени, усилий и нервов. А когда выходят обновления для браузеров и веб-драйвера, начинаются «танцы с бубном» на всех виртуальных машинах.
Также отметим, что нам всегда требуется одновременный прогон тестов на разных конфигурациях (несколько браузеров и разные версии этих браузеров). При таких параллельных запусках потоков Selenium Grid не приносит особой пользы — более того, не справляется и виснет.
С Selenoid всё гораздо проще. Во-первых, для него требуется гораздо меньше ресурсов — как человеческих, так и вычислительных — по сравнению с обычным Selenium Grid, потому что Grid 4, в котором позволяют использовать Docker, всё ещё находится в альфа версии. В текущих стабильных версиях Selenium в процессе Grid-настройки пришлось бы для каждой (!) ноды устанавливать вручную все браузеры, деактивировать им автоматическое обновление и скачивать совместимые с ними веб-драйверы. И этот процесс, в отличие от единовременного создания конфигурационного файла, приходилось бы запускать каждый раз, когда требуется обновить браузер. Для Selenoid же достаточно одной машины для параллельного запуска тестов, одной команды Configuration Manager для разворачивания Selenoid и одной команды для обновления всех браузеров. В Grid тоже можно использовать одну машину, но это не имеет смысла: крайне нежелательно запускать больше одной сессии на одной машине, поскольку браузеры могут влиять друг на друга. Так мы подходим ко второму преимуществу Selenoid. Все сессии на одной машине в Selenoid выполняются в разных контейнерах, а значит, не влияют на работу друг друга.
Итак, на данный момент Selenoid превосходит Selenium Grid во всех отношениях, что и продиктовало наш выбор. После успешных пилотных испытаний мы решили остановиться на использовании Selenoid-платформы для наших основных UI-тестов. Если вы уже используете Selenium и хотите перейти на Selenoid, сделать это несложно: достаточно заменить URL-хаб Selenium на Selenoid.
Где же, каким образом и как часто мы запускаем тесты? Для прогона тестов мы используем систему Jenkins, позволяющую запускать тесты не только вручную, но и автоматически, используя Jenkins Pipeline. Обычно мы запускаем тесты для каждой сборки сами, но поскольку наша компания международная, в нашей команде собраны люди из разных стран. Поэтому новые сборки могут выходить не то что в нерабочие часы, а даже в выходные. Именно поэтому у нас есть особая задача в Jenkins, которая автоматически запускается с выходом новой сборки и обновляет кластеры, после чего запускает остальные задачи в рамках Pipeline, среди которых и прогон тестов.
Во время выполнения задачи в Jenkins на ноде при помощи Pipenv создаётся виртуальная среда для выполнения наших тестов. Сами тесты запускаются при помощи Pytest.
Почему мы решили использовать Pytest в своём FW? Дело в том, что мы используем и параметризацию, и удобные фикстуры, и метки, и плагины. Не будем подробно останавливаться на всех преимуществах Pytest (о нём уже есть много хороших статей на «Хабре», а цель нашей статьи другая), но немного внимания ему всё же уделим.
Параметризацию мы используем, например, для прогона одного и того же теста для пользователей с разным уровнем доступа. Метки позволяют нам запускать тесты только на определённую область функционала системы или пропускать тесты, которые для данной конфигурации не могут быть выполнены. Фикстуры же, благодаря таким их опциям, как возвращаемое значение, позволяют нам удалять только те объекты, которые были созданы во время теста. К примеру, во время теста при помощи каких-то действий в UI были получены объекты. Мы проверяем, успешно ли они создались, смотрим, с правильными ли атрибутами они были созданы в UI и CLI, после чего тест завершается (успешно или нет, неважно). Тогда новосозданные объекты, и только они, удаляются при помощи REST-команд.
Тут у вас могут возникнуть вопросы. Зачем возвращаемое значение, почему бы не удалять все существующие объекты? Ведь достаточно сделать фикстуру, которая после каждого теста/модуля/сессии будет автоматически всё убирать сама. Неужели у вас не хватает систем, на которых вы запускаете тесты? Почему бы тесты, например, для другого браузера не запустить на другой системе, чтобы они не мешали друг другу?
Отвечаем. Да, мы могли бы так сделать, но мы используем параллельный прогон тестов не только для разных браузеров, но и внутри тестового набора. Для этого мы используем Pytest-плагин для распределённого прогона тестов — Xdist. Этот плагин создаёт отдельные процессы и уже среди них распределяет тесты для прогона. Кстати, наш вам совет —старайтесь делать все тесты независимыми, даже если не используете Xdist.
После выполнения тестов результаты можно наглядно рассмотреть и проанализировать при помощи другого плагина – Allure. Он создаёт удобный отчёт для отображения результата прогона тестов, причём не только последнего, но и в динамике: сколько тестов проходило раньше, сколько сейчас, их длительность и т.д. Также благодаря Allure у нас есть удобная фикстура, которая в случае падения теста делает скриншот и прикрепляет его к отчёту, где его можно рассмотреть.
Наглядно всю структуру автоматизации для UI-автотестов в нашем проекте XMS можно представить в виде схемы (рисунок 2).
Рисунок 2. Структура автоматизации UI-автотестов в проекте XMS.
В результате всех этих действий и решений мы имеем отличное окружение для запуска написанных автотестов на разных конфигурациях с отчётностью в Allure и систему контроля качества Quality Center. Мы также автоматизировали Sanity-тесты, которые нужно было прогонять на каждой сборке. Теперь дело остаётся за малым — продолжать писать автотесты и избавляться от рутины. Сейчас мы в процессе написания регрессионных автотестов.
Конечно же, наш путь — не единственный правильный, а лишь один из вариантов, как можно организовать процесс. Нам бы очень хотелось узнать так же подробно, как устроена автоматизация тестирования в ваших компаниях, прочесть обо всех плюсах и минусах этих решений.
Благодарим за внимание!
Ручное тестирование на UI
Если говорить вкратце о том, что такое XMS, то это сервер управления высоконагруженными системами хранения данных (СХД на твердотельных носителях — иными словами, кластер/массив, состоящий из SSD-накопителей). Управление массивом в нашем случае осуществляется с помощью REST API запросов и команд в CLI (Command Line Interface), а также при помощи пользовательского графического интерфейса (GUI). Чтобы примерно понять масштабы тестирования в нашем проекте, попробуйте представить себе огромную лабораторию с невероятным количеством железа и тысячами подсоединённых к нему проводов. К такому серверу можно подключать огромное количество разнообразных плагинов из экосистемы для управления СХД извне и наоборот. А теперь представьте, что каждый элемент этого сервера требует тестирования руками. На рисунке 1, который представлен ниже, вы видите одну из многих страниц нашего UI. На первый взгляд может показаться, что здесь и тестировать нечего, но это только вершина айсберга.
Рисунок 1. Пример UI-страницы из раздела «Безопасность данных» с запущенными собственными сеансами репликации (Native Replication).
Более подробно о Native Replication можно узнать из видео по ссылке.
Ручных тестов на UI чуть больше 3000, и к ним постоянно добавляются новые после очередных доработок продукта. Все наши основные UI-тесты делятся на Display (тесты на отображение всего и вся на страницах сервера; это тесты с самым высоким приоритетом), Display Functionality (тесты на функциональность отображения элементов страницы) со средним приоритетом и Functionality (тесты на функциональность элементов страницы). Последние не менее важны, но идут у нас с низким приоритетом, так как функциональность продукта проверяется нашими коллегами, которые тестируют REST и CLI. Наши тесты мы храним, гоняем и отмечаем в ALM Quality Center от Micro Focus. Это довольно непривычная, но удобная система контроля качества всего процесса тестирования.
На разных циклах тестирования, по нескольку раз в неделю, отдел разработки выпускает новые сборки версий будущего релиза с доработками и исправлениями уже найденных ошибок. Это ещё больше усложняет процесс ручного тестирования, ведь всё, что уже было проверено, могут «сломать» в следующих сборках. Приходится перепроверять каждую версию, чтобы избежать появления сюрпризов, когда продукт уйдёт к серьезным клиентам.
В итоге огромное количество тестов и вся эта ручная и сложная рутинная работа подвигли нас заняться автоматизацией нашего UI. Задача стояла непростая, зато интересная.
Выбор платформы для автоматизации: Selenium Grid или Selenoid?
Рассмотрим подробнее структуру нашей автоматизации. С самого начала мы выбирали между Selenium Grid Hub версий 3 и 4 Alpha, а также присматривались к Selenoid и его более красивому UI-интерфейсу для отладки тестов. Selenoid — это сервер, который при использовании того же Selenium веб-драйвера позволяет запускать браузеры в Docker-контейнерах.
Наверное, многие уже знают, что настройка Selenium Grid на хабах и нодах отнимает очень много времени, усилий и нервов. А когда выходят обновления для браузеров и веб-драйвера, начинаются «танцы с бубном» на всех виртуальных машинах.
Также отметим, что нам всегда требуется одновременный прогон тестов на разных конфигурациях (несколько браузеров и разные версии этих браузеров). При таких параллельных запусках потоков Selenium Grid не приносит особой пользы — более того, не справляется и виснет.
С Selenoid всё гораздо проще. Во-первых, для него требуется гораздо меньше ресурсов — как человеческих, так и вычислительных — по сравнению с обычным Selenium Grid, потому что Grid 4, в котором позволяют использовать Docker, всё ещё находится в альфа версии. В текущих стабильных версиях Selenium в процессе Grid-настройки пришлось бы для каждой (!) ноды устанавливать вручную все браузеры, деактивировать им автоматическое обновление и скачивать совместимые с ними веб-драйверы. И этот процесс, в отличие от единовременного создания конфигурационного файла, приходилось бы запускать каждый раз, когда требуется обновить браузер. Для Selenoid же достаточно одной машины для параллельного запуска тестов, одной команды Configuration Manager для разворачивания Selenoid и одной команды для обновления всех браузеров. В Grid тоже можно использовать одну машину, но это не имеет смысла: крайне нежелательно запускать больше одной сессии на одной машине, поскольку браузеры могут влиять друг на друга. Так мы подходим ко второму преимуществу Selenoid. Все сессии на одной машине в Selenoid выполняются в разных контейнерах, а значит, не влияют на работу друг друга.
Итак, на данный момент Selenoid превосходит Selenium Grid во всех отношениях, что и продиктовало наш выбор. После успешных пилотных испытаний мы решили остановиться на использовании Selenoid-платформы для наших основных UI-тестов. Если вы уже используете Selenium и хотите перейти на Selenoid, сделать это несложно: достаточно заменить URL-хаб Selenium на Selenoid.
Запуск тестов при помощи Jenkins и Pytest. Плагины для Pytest
Где же, каким образом и как часто мы запускаем тесты? Для прогона тестов мы используем систему Jenkins, позволяющую запускать тесты не только вручную, но и автоматически, используя Jenkins Pipeline. Обычно мы запускаем тесты для каждой сборки сами, но поскольку наша компания международная, в нашей команде собраны люди из разных стран. Поэтому новые сборки могут выходить не то что в нерабочие часы, а даже в выходные. Именно поэтому у нас есть особая задача в Jenkins, которая автоматически запускается с выходом новой сборки и обновляет кластеры, после чего запускает остальные задачи в рамках Pipeline, среди которых и прогон тестов.
Во время выполнения задачи в Jenkins на ноде при помощи Pipenv создаётся виртуальная среда для выполнения наших тестов. Сами тесты запускаются при помощи Pytest.
Почему мы решили использовать Pytest в своём FW? Дело в том, что мы используем и параметризацию, и удобные фикстуры, и метки, и плагины. Не будем подробно останавливаться на всех преимуществах Pytest (о нём уже есть много хороших статей на «Хабре», а цель нашей статьи другая), но немного внимания ему всё же уделим.
Параметризацию мы используем, например, для прогона одного и того же теста для пользователей с разным уровнем доступа. Метки позволяют нам запускать тесты только на определённую область функционала системы или пропускать тесты, которые для данной конфигурации не могут быть выполнены. Фикстуры же, благодаря таким их опциям, как возвращаемое значение, позволяют нам удалять только те объекты, которые были созданы во время теста. К примеру, во время теста при помощи каких-то действий в UI были получены объекты. Мы проверяем, успешно ли они создались, смотрим, с правильными ли атрибутами они были созданы в UI и CLI, после чего тест завершается (успешно или нет, неважно). Тогда новосозданные объекты, и только они, удаляются при помощи REST-команд.
Тут у вас могут возникнуть вопросы. Зачем возвращаемое значение, почему бы не удалять все существующие объекты? Ведь достаточно сделать фикстуру, которая после каждого теста/модуля/сессии будет автоматически всё убирать сама. Неужели у вас не хватает систем, на которых вы запускаете тесты? Почему бы тесты, например, для другого браузера не запустить на другой системе, чтобы они не мешали друг другу?
Отвечаем. Да, мы могли бы так сделать, но мы используем параллельный прогон тестов не только для разных браузеров, но и внутри тестового набора. Для этого мы используем Pytest-плагин для распределённого прогона тестов — Xdist. Этот плагин создаёт отдельные процессы и уже среди них распределяет тесты для прогона. Кстати, наш вам совет —старайтесь делать все тесты независимыми, даже если не используете Xdist.
После выполнения тестов результаты можно наглядно рассмотреть и проанализировать при помощи другого плагина – Allure. Он создаёт удобный отчёт для отображения результата прогона тестов, причём не только последнего, но и в динамике: сколько тестов проходило раньше, сколько сейчас, их длительность и т.д. Также благодаря Allure у нас есть удобная фикстура, которая в случае падения теста делает скриншот и прикрепляет его к отчёту, где его можно рассмотреть.
Наглядно всю структуру автоматизации для UI-автотестов в нашем проекте XMS можно представить в виде схемы (рисунок 2).
Рисунок 2. Структура автоматизации UI-автотестов в проекте XMS.
Заключение
В результате всех этих действий и решений мы имеем отличное окружение для запуска написанных автотестов на разных конфигурациях с отчётностью в Allure и систему контроля качества Quality Center. Мы также автоматизировали Sanity-тесты, которые нужно было прогонять на каждой сборке. Теперь дело остаётся за малым — продолжать писать автотесты и избавляться от рутины. Сейчас мы в процессе написания регрессионных автотестов.
Конечно же, наш путь — не единственный правильный, а лишь один из вариантов, как можно организовать процесс. Нам бы очень хотелось узнать так же подробно, как устроена автоматизация тестирования в ваших компаниях, прочесть обо всех плюсах и минусах этих решений.
Благодарим за внимание!
Комментарии (3)
conopus
19.08.2021 19:06Вобщем-то класссический стэк для Web UI тестов на Python. Такой, наверное, в большинстве компаний применяется, где тесты пишут на Python.
lxsmkv
Сколько времени у вас уходит/уходило на прогон всех 3К ручных тестов?
Сколько человек занято в автоматизации тестирования этого проекта?
Какую долю "ручных" тестов вы уже автоматизировали?
Как введение автоматизации повлияло на распределение рабочей нагрузки "ручных" тестировщиков
Как и кто решает какие тесты автоматизировать?
--
На моем проекте сейчас используется Ranorex, там тесты гоняются на виртуальных машинах windows, поскольку эмулируются действия пользователя. В этом есть свой резон. Тесты максимально приближены к картине пользователя. Т.е. браузер практически черный ящик.
Под линукс однако драйверов нет. Поддерживает тестирование десктопных и мобильных приложений. У инструмента низкий порог вхождения. Хорошая документация. Можно легко делать гибридные сценарии, например, загрузка файла через окно Explorer.
Но есть и свои недостатки. Если сразу не поставить правильно архитектуру, модуляризацию и не договориться о правилах, то можно нагородить такой огород, что черт ногу сломит. Еще, поскольку используется кодогенерация, коммиты практически невозможно нормально ревьюить.
А так, тоже интеграция с jenkins, удобные отчеты из коробки, сразу с картинками. Можно скриншотить что хочешь и когда хочешь и все это попадает в лог. Есть PDF экспорт логов. Есть junit совместимый отчет. Можно по желанию вести видеозапись по ходу выполнения. Интеграция с Jira, он может выкидывать ошибки прямо туда. Интеграция с Xray.
Если нужны кастомные действия, типа доступ к базе данных, или REST, можно писать их на C#. Ну и он денежек стоит, хотя не так много как некоторые другие. Там пожизненная лицензионная модель, пока. Есть 30-дневный трайал. Хороший саппорт, много записей вебинаров у них на странице.
rus_ski
Все сразу 3К ручных тестов мы не гоняем. В зависимости от различных параметров (циклов тестирования и областей тестирования), мы делаем выборку из всех существующих тестов и гоняем только её. В среднем, одному человеку для прогона 100 ручных тестов требуется 1 месяц, т. к. длительность выполнения одного теста может занимать как несколько минут, так и несколько дней.
На данный момент 2 человека заняты автоматизацией.
На сегодня у нас автоматизировано около 130 тестов.
Для каждого регрессионного цикла прогон 130 автотестов экономит чуть больше месяца ручного тестирования. Также тестировщикам нет необходимости «руками» прогонять Sanity тесты после еженедельного выхода новой сборки.
На общей встрече с командой заводим задачи на автоматизацию в backlog и оттуда уже берём задачи.
Спасибо, не знали о таком решении, ознакомимся.