<style>.lazy{display:none}</style>6 способов параллельного автоматизированного тестирования UI с помощью Selenium

6 способов параллельного автоматизированного тестирования UI с помощью Selenium

Реализация протоколов Selenium в виртуальных машинах, Docker, Kubernetes и облаке.

Свой первый кластер Selenium Grid я создал около пяти лет назад. Вся система (см. рисунок выше) состояла всего из двух MacBook Pro. Первый ноутбук служил центральным сервером сети и узлом, а второй – вторым узлом сети. Оба узла были настроены на запуск и взаимодействие с Chrome, Firefox, эмуляторами Android и iOS для тестирования пользовательского интерфейса путем установки программ и их зависимостей непосредственно в операционную систему. Как бы просто это ни звучало, на деле это оказалось сложным в настройке и, что еще хуже, в обслуживании.

В этой статье мы рассмотрим Selenium Grid и Selenoid/Moon для параллельного тестирования пользовательского интерфейса веб- и мобильных приложений, их интеграцию с конвейером CI/CD, способы организации ресурсов для обеспечения эффективности и масштабируемости, проблемы, которые были решены, и те, которые все еще остаются нерешенными. Тестирование пользовательского интерфейса не ограничивается только реализациями на базе протокола Selenium, есть и новые интересные технологии, например Playwright. Однако это достаточно широкая тема, и Selenium по-прежнему остается наиболее распространенным фреймворком для автоматизации тестирования пользовательского интерфейса, существующим с 2004 года.

Подпишитесь на наш ТЕЛЕГРАМ КАНАЛ ПО АВТОМАТИЗАЦИИ ТЕСТИРОВАНИЯ

Локальное параллельное тестирование

Прежде чем перейти к рассмотрению организации работы на стороне сервера, давайте рассмотрим сторону клиента, поскольку параллельное тестирование все равно не будет иметь места, пока ваш тестовый фреймворк не сможет запускать тесты параллельно.

Это можно сделать двумя способами:

  1. Первый способ – это forking. Вместо того чтобы порождать несколько потоков, создаются новые процессы, при наличии тестовых классов. В Java это можно сделать в Maven с помощью плагина Failsafe и в Gradle с помощью опции maxParallelForks. Допустим, ваш тестовый фреймворк использует Gradle с maxParallelForks = 2, и у вас есть как минимум два класса тестовых прогонов. Когда вы запускаете в Jenkins задание на выполнение тестов в Chrome, два браузера Chrome будут запускать и выполнять тесты одновременно.
  2. Второй способ – разделить тесты на партии, чтобы каждая партия была нацелена на разные браузеры на одном или разных дисплеях. Один из способов разделения тестов – это создание профилей Maven для каждой партии и, наконец, настройка конвейера Jenkins на одновременный запуск в нескольких заданиях и объединение результатов тестирования в конце.

Можно использовать один из двух рассмотренных методов, а можно и оба вместе. Так, если у вас есть два пакетных задания в дополнение к двум форкам, то общее количество одновременно работающих браузеров будет равно четырем.

Для локального запуска тестов на браузерах пакет Selenium Server не нужен. Однако для локального и удаленного запуска тестов на Android и iOS необходим Appium Server.

До версии Appium 1.7 единственным способом запуска нескольких виртуальных и реальных мобильных сред на одном хосте была установка нескольких серверов Appium Server, их запуск на разных портах и сопряжение одной среды с одним портом Appium Server. Посмотрите на первую схему в этой статье, где на узле B (node B) настроены три сервера Appium Server на портах 4723, 4724 и 4725 для одного симулятора и двух эмуляторов.

В Appium 1.7 и выше один сервер Appium Server может запускать несколько сред, если подключить несколько Android-устройств к одному серверу Appium Server на разных системных портах, а затем указать эту возможность в коде клиента для подключения к нужной среде. Для iOS-устройств драйверная возможность называется wdaLocalPort. Обратите внимание, что запуск нескольких iOS-симуляторов на одном хосте возможен только начиная с Xcode 9.

Это самая простая форма параллельного тестирования, поскольку все может происходить на одном хосте. Но мы стремимся к увеличению количества хостов и разнообразию комбинаций ОС/браузеров для одновременного запуска. Кроме того, нельзя быть уверенным в том, что на одном хосте можно надежно запустить несколько сред одновременно. Более того, изменение фокуса на запуск в нескольких средах может замедлить работу.

Selenium Grid на виртуальных машинах/реальных устройствах

Selenium Grid – один из компонентов пакета Selenium, состоящий из центрального сервера (хаба) и подключаемых к нему узлов. Хаб выступает в роли прокси-сервера, принимающего запросы от клиента WebDriver и передающего JSON-команды удаленным драйверам на узлах для выполнения тестов.

Назначение хаба и узлов происходит во время запуска пакета Selenium Server. По умолчанию без каких-либо пользовательских настроек запуск узла позволяет одновременно использовать 5 Firefox, 5 Chrome и 1 Internet Explorer. Вы также можете настроить свой Appium Server на подписку на хаб грида, что позволит удаленно выполнять тесты на эмуляторах Android, iOS и реальных устройствах.

Распределенная сетка дает следующие преимущества:

  1. Одновременное выполнение тестов на разных браузерах и операционных системах.
  2. Если один из узлов выйдет из строя, хаб передаст тесты на другие узлы, поэтому не нужно в последний момент искать другую машину, устанавливать необходимые пакеты, настраивать возможности узла, подписываться на хаб и, наконец, запускать тесты.

Как я уже говорил в начале статьи, я начал работу с Selenium Grid с ручной установки необходимого программного обеспечения непосредственно на операционную систему, которая может быть либо хостовой ОС, либо гостевой ОС на гипервизоре. Вот что не так с этой установкой:

  1. Наиболее очевидным недостатком является хаб сети. Это единая точка отказа. Если он выйдет из строя, то не будет другого способа связаться со всеми узлами. И нет, вы не можете разместить несколько хабов за балансировщиком нагрузки для обеспечения отказоустойчивости, поскольку Selenium Server является stateful сервером, и экземпляры не обмениваются сессиями друг с другом.
  2. Такое решение не масштабируется. Хаб часто упоминается как неэффективная Java-реализация, которая может поддерживать только несколько узлов. Наращивание мощности для достижения производительности за счет вертикального масштабирования не поможет и не оправдывает затрат. В данной статье предлагается использовать в качестве узла VM, имеющую всего 2 VCPU и 4 Гбайт оперативной памяти.
  3. Добавить дополнительные узлы легко не получится. Необходимо вручную повторять задачи установки и настройки на каждом новом узле, который необходимо добавить в сеть.
  4. Проблема при синхронизации версий. Например, последняя версия веб-драйвера может не работать вместе с версией браузера, особенно если вы хотите протестировать более старую версию браузера. Или, например, для тестирования новой ОС Android необходимо обновить сервер Appium Server.
  5. Нерациональное использование ресурсов. Хаб и все его узлы постоянно работают – если только вы не останавливаете и не запускаете их вручную по одному, когда вам нужно провести несколько тестов.
  6. Неактуальные ресурсы. Известно, что через некоторое время сеть узлов приходит в плохое состояние, поэтому время от времени требуется ручная перезагрузка.
  7. Как установить и протестировать разные версии одного и того же браузера на одной и той же операционной системе? Ответ: никак. Обновление ОС Windows удаляет старые версии IE и Edge.
  8. В хабе нет возможности автовосстановления Appium Server (для мобильных сред) в случае его сбоя.
  9. Поскольку виртуальная машина постоянно находится в рабочем состоянии, браузеры подвержены нехватки памяти и процессов. В итоге вы получите медленный просмотр веб-страниц или браузер, который долго запускается.
  10. Виртуальные машины, такие как VirtualBox и VMWare, были созданы для снижения стоимости и повышения эффективности за счет использования нескольких операционных систем в изолированных средах на одной машине. Однако виртуальные машины, являясь полной копией операционной системы, могут занимать много системных ресурсов.

Для тех, кому интересно, дальнейшее описание механики этого решения можно найти на странице на Github.

В предстоящем выпуске Selenium, Selenium Grid 4, будет полностью переписан. Помимо традиционного режима “узел-центральный сервер”, новая сеть будет поддерживать автономный режим, в котором все запускается локально, и полностью распределенный режим, который раскрывает оригинальную внутреннюю структуру хаба, предлагая каждый компонент (маршрутизатор, карту сессий и дистрибутор) в качестве отдельного процесса. Распределенный режим позволяет лучше отлаживать и устранять неполадки, если что-то идет не так. Он также позволит лучше использовать возможности современных технологий, таких как Docker, Kubernetes и облако.

Selenium-Docker

С появлением контейнеризации как способа стандартизации упаковки приложений и зависимостей для работы в различных вычислительных средах я вскоре перешел к использованию Selenium-Docker, образов контейнеров, которые так любезно предоставляет нам компания Selenium.

Преимущества использования Selenium-Docker очевидны:

  1. Теперь стало проще масштабировать количество узловых контейнеров, запускать и останавливать их с помощью docker-compose.
  2. Можно не мучиться с настройкой и поддержкой сети узлов. Достаточно указать версию браузера, которую вы хотите использовать, и все необходимые зависимости уже готовы в образе. Вам также не придется возиться с синхронизацией версий.
  3. Более стабильное тестирование, поскольку сетка не остается запущенной на длительный период времени, что повышает вероятность сбоя.
  4. Отсутствие лишних ресурсов. Тестовые ресурсы создаются по требованию и уничтожаются по завершении тестирования.
  5. Вы можете сосредоточиться на выполнении тестов только на одной среде в контейнере, поскольку легко создать новую. На самом деле это предпочтительнее, поскольку выполнение тестов на нескольких мишенях в одном узле ненадежно.
  6. Эфемерная архитектура тестов означает, что потенциально можно избавиться от этапа staging или QA-тестирования. Разработчики и тестировщики, скорее всего, с большей охотой примутся за тестирование функциональной ветки, если они смогут быстро запустить контейнерное приложение и контейнерную Selenium Grid в CI. Каждая ветка принимается и фиксируется при прохождении тестов, поэтому нет необходимости проводить еще один цикл тестирования, в котором проверяется ветка разработки или основная ветка. Это также способствует ранней обратной связи в цикле разработки.

К нерешенным проблемам, которые не могут быть решены Selenium-Docker в режиме “узел-центральный сервер”, относятся:

  1. Факт остается фактом: хаб может работать только с ограниченным числом узлов, что делает бесполезной возможность легкого добавления новых узлов в сетку.
  2. Хаб по-прежнему является единой точкой отказа.
  3. Для автомасштабирования, автовосстановления и мониторинга контейнеров Selenium можно дополнительно использовать средства оркестровки контейнеров, например Kubernetes, но бессмысленно использовать такие мощные средства, если хаб сети не рассчитан на отказоустойчивость и не способен работать с большим количеством узлов.

Selenoid

Selenoid был создан для устранения недостатков хаба. Он решает эту проблему, по сути, избавляясь от Selenium Server, единственной обязанностью которого является запуск и проксирование всех сеансов Selenium на веб-драйверы. Ранее Selenium Server делал не только это, но с появлением geckodriver для Firefox в дополнение к chromedriver для Chrome и safaridriver для Safari все стало гораздо проще.

Эти качества делают Selenoid лучшим решением:

  1. Это легкий “демон”, написанный на языке golang, в отличие от громоздкого Selenium Server.
  2. Менеджер конфигурации Selenoid позволяет очень просто установить Selenoid и контейнеры. Достаточно одной команды, чтобы установить и запустить “демон”, который запускает контейнеры в зависимости от требуемых возможностей, а затем направляет тестовые запросы на Webdriver в контейнерах.
  3. Для каждого теста запускается новый контейнер с браузером, что позволяет каждый раз получать новый браузер в изолированной и стабильной среде. Вам больше не нужно беспокоиться о том, что кэш браузера и его настройки могут повлиять на другой тест.
  4. По умолчанию каждый Selenoid запускает пять параллельных сессий. Этот параметр может быть настроен в зависимости от аппаратных возможностей. Рекомендуемое значение – количество ядер процессора * 1,5-2. При использовании балансировщика нагрузки Ggr, также разработанного теми же специалистами, для распределения нагрузки между несколькими экземплярами Selenoid, можно создать кластер Selenoid, который действительно масштабируется.
  5. Вместе с Selenoid предлагается пользовательский интерфейс Selenoid UI, позволяющий просматривать экраны браузера в реальном времени, журналы сеансов и потребление браузера для устранения неполадок.
  6. Доступны актуальные образы Docker для Firefox, Chrome, Opera и Android.

Далее возникает вопрос – чего нельзя делать с помощью Selenoid?

  1. Нет смысла использовать Selenoid с инструментами оркестровки контейнеров. Selenoid запускает контейнеры браузеров с помощью Docker API, поэтому все браузеры будут запускаться только на одном узле Kubernetes.
  2. Selenoid предназначен только для кроссбраузерного тестирования, но не для мобильных приложений.

Moon

Moon – это коммерческий продукт, созданный теми же людьми, что и Aerokube, который работает аналогично Selenoid, но предназначен для работы с Kubernetes и OpenShift. Вы можете использовать его бесплатно, запустив до четырех параллельных браузерных подсистем.

Особенности, которые делают Moon еще лучше, чем Selenoid:

  1. Вместо запуска контейнеров через Docker API, Moon запускает и останавливает браузерные поды с помощью Kubernetes API.
  2. Moon полностью статичен. Это позволяет реплицировать Moon в разных центрах обработки данных. Браузерные сессии сохраняются, если одна или несколько реплик выходят из строя.
  3. Автоматическое масштабирование в зависимости от нагрузки.
  4. Moon доступен на рынках DigitalOcean и Google Cloud. Всего за несколько кликов можно установить кластер Kubernetes с Moon. Для использования другого облачного провайдера можно создать кластер Kubernetes, а затем применить готовые к использованию манифесты Moon.

Как и Selenoid, Moon не обеспечивает поддержку мобильных сред.

Облачные решения

Поставщики облачных платформ тестирования, такие как Sauce Labs, BrowserStack и Perfecto Mobile, позволяют выполнять веб- и мобильные тесты в облаке. Большинство людей, обратившихся к этим провайдерам, сделали это потому, что:

  1. Они поддерживают практически все существующие операционные системы, включая Safari, IE и Edge.
  2. Они берут на себя все заботы по обновлению, обслуживанию, подключению и зарядке устройств, что позволяет избежать ситуаций, когда во время тестирования (на реальном устройстве) вас просят подтвердить обновление ПО.
  3. Интеграция с популярными CI.
  4. Как правило, они очень быстро предлагают бета-версии новых релизов.
  5. Sauce Labs предоставляет открытым проектам бесплатный доступ к большому количеству браузеров, реальных и виртуальных устройств (до пяти одновременных сессий для параллельного тестирования).
  6. Высокая доступность от Sauce Labs за счет настройки пула туннелей Sauce Connect.

Звучит так, будто это ответы практически на все проблемы наших предыдущих решений. Так почему же вы не захотите подписаться на одну из них?

  1. Они недешевы (если вы не используете открытый код), и это вполне ожидаемо, поскольку реальные и виртуальные ОС и устройства по вашему выбору резервируются для вас и только для вас до завершения ваших тестов.
  2. Sauce Labs запускает новую VM для каждого теста. VM работают медленнее, чем контейнеры, у которых меньше дополнительных затрат ресурсов. Задержки могут быть значительными при выполнении нескольких тестов.
  3. Настройка и поддержка может быть достаточно сложной, если ваше приложение находится за корпоративным брандмауэром или существует внутренний сетевой прокси.
  4. Они действительно снимают с вас большую часть забот по обслуживанию, но не все. Когда что-то идет не так, вам все равно приходится тратить время на анализ журналов, чтобы понять, ваша это проблема или их проблема, прежде чем нажать красную кнопку, чтобы предупредить их о том, что на их стороне что-то пошло не так.

Не Selenium решения

Стоит кратко остановиться на поддержке параллельного тестирования в других реализациях, не относящихся к классу Selenium. Наиболее популярными из них являются Playwright от Microsoft, Puppeteer от Google и Cypress.

Playwright является своего рода преемником Puppeteer, так как основные разработчики Playwright работали над Puppeteer до того, как покинули его. Playwright поддерживает Chromium (Google Chrome и новый Microsoft Edge), Firefox и WebKit. Cypress поддерживает первые два браузера, а Puppeteer в настоящее время поддерживает только Chromium.

Playwright – основной соперник Selenium, поддерживающий широкий спектр браузеров, причем версия 1.0 вышла всего несколько месяцев назад. В Playwright JSON-объекты передаются через WebSocket, который поддерживается в течение всего времени работы, в отличие от Selenium, который отправляет HTTP-запрос для каждой тестовой команды.

Одной из особенностей Playwright, делающей его принципиально новым, является новая концепция, называемая контекст просмотра. Контекст просмотра может содержать несколько веб-компонентов и контекстное поведение, эмулировать мобильные устройства и имитировать геолокацию. Это позволяет параллельно реализовывать многостраничные сценарии на различных конфигурациях устройств, таких как iPhone, iPad и настольные компьютеры. Все это возможно при использовании всего одного экземпляра браузера.

Cypress – еще одна популярная реализация кросс-браузерной автоматизации с поддержкой параллельного тестирования в лицензионной версии, на которую стоит обратить внимание.

Заключение

Итак, вот и все. Шесть различных способов параллельного выполнения автоматизированных тестов пользовательского интерфейса. Если кратко, то это:

  1. Локальный запуск с использованием методов forking и batching на стороне клиента, а также установка Appium Server для одновременного тестирования на нескольких мобильных устройствах.
  2. Удаленные запуски с помощью Selenium Grid на VM в режиме хаба и узла.
  3. Удаленный запуск через selenium-docker. Мы убедились, что до появления Selenium Grid 4 нет смысла запускать Selenium Grid с докером на средствах оркестровки контейнеров.
  4. Удаленный запуск через Selenoid, работающий с Docker API напрямую.
  5. Удаленные запуски через Moon, работающие с Kubernetes и OpenShift.
  6. Удаленные запуски через провайдеров облачных тестов, таких как Sauce Labs и BrowserStack.

Три дополнительных способа, которые станут возможны благодаря грядущему выпуску Selenium Grid 4:

  1. Удаленный запуск через Selenium Grid в автономном режиме.
  2. Удаленные запуски через Selenium Grid в полностью распределенном режиме (с Kubernetes или без нее).
  3. Локальный запуск через Selenium IDE.

Выбор того или иного варианта зависит от масштаба и зрелости проекта, имеющегося бюджета, ресурсов, навыков и времени. Мы не рассматривали Zalenium, проект с открытым исходным кодом, предоставляющий дополнительные функции поверх гибкой и одноразовой Selenium Grid, в качестве жизнеспособного варианта, поскольку он перестал поддерживаться с марта 2020 года.

Мы также обсудили плюсы и минусы каждого решения. Вердикт таков: Selenoid/Moon (решения 4 и 5) очень перспективны для браузерного тестирования на базе API Selenium и Playwright.

Для крупномасштабного тестирования на мобильных устройствах большинство людей обращается к облачным провайдерам тестирования (решение 6). Я бы отнесся к этому с сомнением, основываясь на своем предыдущем опыте работы с одним из них. Однако других вариантов просто не существует, если только в вашей организации нет команды, занимающейся управлением собственной фермой виртуальных/реальных устройств, а это очень сложно. Аналогов Selenoid/Moon для тестирования мобильных приложений также не существует, так что вам остается только Selenium Grid (решения 2 и 3) или несколько сред на одной машине с Appium (решение 1).

Возможно, чтобы сократить количество UI-тестов, лучше еще раз проанализировать свои UI-тесты и задать себе следующие вопросы: Следует ли их отнести к тестам более низкого уровня? Подходят ли эти тесты для изменений в коде?

Перевод статьи «6 Ways to Do Automated UI Testing in Parallel With Selenium».

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *