Selenium параллельный запуск тестов

Содержание
  1. Запуск Selenium параллельно с любым инструментом модульного тестирования .NET
  2. Постановка задачи
  3. DynamicObject
  4. Использование операторов и конструктора
  5. TryInvokeMember
  6. TryGetMember
  7. TrySetMember
  8. Вызов ParallelPageModel
  9. Соображения
  10. Другие места, говорящие о параллельном селене
  11. Автоматизация тестирования с помощью Selenoid
  12. Особенности работы с Selenium Grid
  13. Для установки Selenium Grid понадобится:
  14. Что можно предпринять?
  15. Selenoid как альтернатива
  16. Selenoid vs. Selenium Grid
  17. Дополнительные возможности Selenoid
  18. Подводя итог
  19. Как выполнять много UI-тестов параллельно, используя Selenium Grid?
  20. Известные решения
  21. Исследование
  22. Автоматизация тестирования с помощью Selenoid
  23. ОСОБЕННОСТИ РАБОТЫ С SELENIUM GRID
  24. Для установки Selenium Grid понадобится:
  25. ЧТО МОЖНО ПРЕДПРИНЯТЬ?
  26. SELENOID КАК АЛЬТЕРНАТИВА
  27. SELENOID VS. SELENIUM GRID
  28. Параллельный запуск тестов Все стартует в одном окне браузера
  29. #1 OxanaKIseleva
  30. #2 BabyRoot
  31. #3 OxanaKIseleva
  32. #4 BabyRoot
  33. #5 OxanaKIseleva
  34. #6 BabyRoot
  35. #7 OxanaKIseleva
  36. #8 OxanaKIseleva
  37. #9 BabyRoot
  38. #10 OxanaKIseleva
  39. #11 OxanaKIseleva
  40. #12 BabyRoot
  41. #13 OxanaKIseleva
  42. #14 BabyRoot
  43. #15 OxanaKIseleva
  44. #16 BabyRoot
  45. #17 OxanaKIseleva

Запуск Selenium параллельно с любым инструментом модульного тестирования .NET

В то время как мои предпочтительные инструменты тестирования — NUnit и SpecFlow , метод, который я собираюсь предложить, должен работать с любым существующим тестовым набором, который вы, возможно, захотите использовать. Единственным предварительным условием является использование моделей страниц для переноса доступа к любой конкретной веб-странице.

В этой статье предполагается, что вы:

  • Уже умею писать тесты Selenium
  • Уже знаете, как использовать Selenium Grid
  • Уже знаете, как использовать шаблон Page Model
  • Уже знаете, как использовать выбранный вами тестовый ремень.

ХОРОШО. На главном событии.

Постановка задачи

Для одновременного запуска нескольких браузеров самый простой способ — предоставить модель страницы-обертки, которая одновременно вызывает несколько экземпляров модели страницы.

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

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

DynamicObject

Введите малоизвестный класс, DynamicObject . В .NET 4 Microsoft ввела динамическое ключевое слово. Одно из основных применений — для мест, где вам нужно иметь возможность объявить переменную в вашем коде, которую компилятор не будет знать, как разрешить тип до времени выполнения. Я мог бы использовать это несколько лет назад, когда у меня было две сборки, которые должны были ссылаться друг на друга. В этом случае я использовал отражение. Но динамический работал бы с гораздо меньшим количеством работы.

DynamicObject — это особый класс, который позволяет нам разрешать вызовы свойств и методов во время выполнения, используя нашу собственную логику.

Мы также будем использовать библиотеку Task Parallel для реализации наших параллельных вызовов.

Для полноты и того, чтобы никто не запутался, пытаясь реализовать этот код, вам понадобятся следующие операторы using в верхней части файла CS.

Использование операторов и конструктора

Итак, начнем. Первое, что нам нужно, это объявление класса:

TPage позволяет нам определять интерфейс, который реализует реальная модель страницы. Да, нам все еще нужен интерфейс, но нам не нужно создавать новый класс-обертку для каждой модели страницы, которую мы хотим обернуть.

Класс наследуется от DynamicObject, так что все наше совершенство на лету будет работать.

Далее нам понадобится место для хранения массива PageObjects, которые мы хотим прокси. Поэтому мы добавляем приватную переменную _page для этой цели.

Используя TPage [], мы создаем переменную того же типа, что и модели страниц, которые мы используем.

Далее нам нужен конструктор.

Используя ключевое слово params, мы можем передавать объекты страницы как массив или как отдельные параметры.

Волшебство происходит в трех переопределенных методах, которые находятся в DynamicObject:

  • TryInvokeMember — разрешает любые вызовы методов.
  • TrySetMember — разрешает любые установщики свойств
  • TryGetMember — разрешает любые свойства get

Итак, давайте добавим эти методы дальше:

TryInvokeMember

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

Когда я впервые понял это, я начал с реализации цикла foreach, но мы собираемся перейти к использованию Parallel.ForEach ().

Parallel.ForEach () позволит нам передать массив и запустить лямбда-выражение для каждого элемента в массиве. Итак, наш цикл foreach будет выглядеть так:

Обратите внимание, что наше лямбда-выражение не делает ничего, кроме простого вызова отражения.

Возвращаемый результат добавляется в нашу коллекцию ConcurrentBag. ConcurrentBag — это коллекция, специально созданная для параллельных вызовов. У нас могут возникнуть проблемы, если мы добавим что-то в коллекцию List <>, если не добавим некоторый контроль параллелизации вокруг него. Я за то, чтобы делать как можно меньше работы.

Второе, что мы хотим сделать, это обработать возвращаемые результаты.

Для этого нам нужно настроить базовый цикл foreach.

Внутри цикла foreach мы обработаем сбор результатов.

Если возвращенный тип совпадает с типом, для которого страница проксирует, мы просто устанавливаем наше значение результата, возвращаемое нами значение TryInvokeMember вернет нам код, который вызвал прокси, равный прокси объект.

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

Наконец, мы просто устанавливаем результат на то, что имеем на данный момент.

И затем последнее, что мы хотим сделать, это вернуть true, чтобы сообщить системе, что мы смогли обработать метод.

TryGetMember

Поскольку реализация TryGetMember очень похожа на TryInvokeMethod, мы займемся этим дальше.

Фактически, единственное различие между этими двумя методами — это код внутри блока параметров Parallel.ForEach.

TrySetMember

TrySetMember — это самая легкая реализация из всех, так как не о чем беспокоиться.

Таким образом, приведенный выше код будет работать, но вы не получите никакой помощи IntelliSense от Visual Studio, если будете использовать этот код без его настройки.

Нам нужен какой-то способ приведения объекта ParallelPageModel к типу TPage, который мы передаем.

Для этого мы собираемся использовать классную библиотеку ImpromptuInterface, которую я нашел .

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

И тогда вам нужно будет добавить этот метод в класс ParallelPageModel.

Вы бы использовали это так:

Где IMyPageModel — это интерфейс, который определяет, как выглядит ваш настоящий класс PageModel.

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

Вызов ParallelPageModel

Чтобы настроить ParallelPageModel, ваш код должен выглядеть примерно так, если предположить, что у вас есть класс модели страницы MyPageModel с интерфейсом IMyPageModel.

Соображения

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

Например, я предполагаю, что вы имеете дело только с простыми типами или типом модели страницы, для которой вы являетесь прокси. Здесь нет кода, который бы обрабатывал ситуацию, когда вызов метода вернул бы совершенно новую модель страницы. Поскольку код, который я тестирую, представляет собой набор одностраничных приложений, и я не тестирую навигацию на этом этапе, это не является для меня вопросом. Но это было бы относительно легко реализовать. Если бы я это сделал, я бы, вероятно, справился бы с этим, но создал бы подкласс этого основного класса, который выполняет основную часть работы и переопределяет метод Try * Member, который необходим для решения этой ситуации.Другой возможный способ справиться с ситуацией — передать список типов, которые необходимо обернуть в их собственный объект распараллеливания, в качестве параметров в конструкторе и добавить некоторый общий код в класс ParallelPageModel.

Читайте также:  Стенки пищевода образованы тканями тест

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

Вот весь класс в одном куске для тех из вас, кто просто хочет скопировать и вставить решение.

Другие места, говорящие о параллельном селене

И конечно же куча ссылок на людей, спрашивающих, как этого можно достичь.

Источник

Автоматизация тестирования с помощью Selenoid

Многие команды инженеров по тестированию ПО при выполнении автоматизированных тестов отдают предпочтение такому инструменту, как Selenium Grid. Данное решение позволяет получить распределенную среду для параллельного выполнения большого количества тестов. Однако в процессе работы над проектом могут возникать определенные сложности. Их можно избежать, если вместо Selenium Grid использовать Selenoid.

Читайте дальше и вы узнаете об:

  • Особенностях работы с Selenium Grid.
  • Преимуществах и возможностях Selenoid.

Особенности работы с Selenium Grid

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

Решение это популярное, но при работе с ним инженеры по автоматизации должны иметь в виду следующие особенности:

  • Длительный процесс развертывания

Для установки Selenium Grid понадобится:

  1. Скачать и установить Java Development Kit.
  2. Найти и скачать актуальную версию Selenium Server JAR.
  3. Скачать необходимые версии веб-драйверов.
  4. Распаковать веб-драйвера из архивов.
  5. Установить необходимые версии браузеров.
  6. Ввести ряд длинных команд в командную строку.

Этапы установки Selenium Grid

  • Сложные команды запуска

Вот примеры команд для старта сервера и узлов:

Команды для старта серверов и узлов

  • Снижение скорости работы

При использовании большого количества нод с разными браузерами хаб начинает работать достаточно медленно.

Важно следить, чтобы версии нод и браузеров были совместимы. Иначе может возникнуть конфликт.

Что можно предпринять?

Некоторые сложности, например, длительный процесс установки, могут быть преодолены.

Оптимизировать процесс поможет Docker – контейнерная платформа для быстрой сборки, отладки и развертывания приложений.

После создания образа можно переходить к созданию контейнера, который будет содержать все необходимое для работы приложения: библиотеки, системные инструменты, код и среду исполнения.

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

Selenoid как альтернатива

Чем можно заменить Selenium Grid? Достойным вариантом является Selenoid – инструмент, с помощью которого можно быстрее и проще запускать браузеры в Docker-контейнерах. Процесс отличается от аналогичного в Selenium.

Для каждого запроса нового браузера Selenoid запускает новый контейнер и останавливает его после закрытия сессии.

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

Selenoid написан на языке Golang и поддерживает все востребованные браузеры.

Selenoid vs. Selenium Grid

Цель использования данных решений одна – создание единой среды для параллельного запуска автотестов. При этом между решениями существует ряд важных отличий. В чем же преимущества Selenoid?

  • Изолированное окружение

В Selenoid каждый браузер запускается в отдельном контейнере, что позволяет полностью изолировать окружение браузера.

При использовании Selenium Grid существует вероятность, что настройки браузера могут быть изменены.

В процессе работы с Selenium Grid после создания большого количества нод тесты могут перестать выполняться.

В Selenoid окружение никак не влияет на качественное и непрерывное проведение тестов.

  • Потребление и утилизация ресурсов

Поскольку Selenium Server написан на Java, расход ресурсов при большой нагрузке значительно возрастает.

Selenoid позволяет поддерживать высокую нагрузку без дополнительных ресурсозатрат.

В среднем при десяти запущенных сессиях Selenium Server на Java потребляет 500 МБ оперативной памяти, в то время как Selenoid – всего 50–60 МБ.

Кроме того, Selenoid утилизирует все неактивные контейнеры после завершения сессии, тем самым постоянно поддерживая нужное количество свободной памяти.

В отличие от достаточно длительного процесса развертывания Selenium Grid, установка Selenoid не займет много времени. Главное – установить Docker и ввести лишь одну команду.

  • Одновременная поддержка нескольких версий одного браузера

Данная опция доступна лишь у Selenoid. Для этого нужно создать несколько контейнеров с необходимыми браузерами.

Нужно помнить о том, что при работе с Selenium Grid могут появиться проблемы при запуске нескольких браузеров на одной машине.

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

В Selenoid такой проблемы нет, поскольку каждый тест запускается в отдельном контейнере.

  • Пользовательский интерфейс и логи

В Selenium Grid возникают сложности при получении логов определенных браузерных сессий. В то время как Selenoid позволяет быстро получить доступ к имеющимся журналам.

Помимо этого, есть возможность интеграции с ELK стеком для более быстрого сбора и анализа текущих файлов регистрации.

Также Selenoid достаточно удобен в использовании и располагает информативным интерфейсом.

Дополнительные возможности Selenoid

Помимо вышеупомянутых преимуществ, Selenoid обладает рядом дополнительных функций, которые способствуют оптимизации работы.

  • Хранение данных в оперативной памяти

В Selenoid все временные файлы хранятся в Tmpfs.

Tmpfs – это временное файловое хранилище, которое позволяет хранить файлы в оперативной памяти. Доступ к ОЗУ, как известно, осуществляется намного быстрее, чем к файловой системе жесткого диска.

  • Различное разрешение экрана

Selenoid позволяет самостоятельно настраивать подходящее разрешение экрана для запущенного контейнера. Сделать это можно посредством выставления необходимых параметров в настройках компонента Browser Capabilities.

  • Отображение экрана браузера

В Selenoid во время исполнения тестов существует возможность подключиться к порту VNC в режиме реального времени, получить доступ к экрану нужного браузера и даже вмешаться в процесс исполнения автотеста.

Selenoid позволяет проводить видеозапись исполняемых тестов.

Активация записи в Selenoid на примере браузера Google Chrome происходит за счет выставления параметра true в соответствующую настройку компонента Browser Capabilities:

ChromeOptions options = new ChromeOptions();

Подводя итог

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

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

А у вашей команды есть опыт работы c Selenoid?

Заказать консультацию по автоматизации тестирования специалистов a1qa можно здесь.

Источник

Как выполнять много UI-тестов параллельно, используя Selenium Grid?

Всем привет! Я работаю в Avito и занимаюсь разработкой инструментов для тестирования. Когда у нас стало много UI-тестов, мы столкнулись с проблемой масштабирования Selenium-серверов, и сейчас я расскажу, как мы ее решили.

И так как же все-таки выполнять много UI-тестов параллельно, используя Selenium Grid? К сожалению — никак.
Selenium Grid не способен выполнять большое количество задач параллельно.
Хотите зарегистрировать действительно большое количество нод? Что ж, попробуйте.
Хотите скорости? Её не будет — чем больше нод зарегистрировано на гриде, тем менее стабильно выполняется каждый тест. Как следствие — перезапуски.
Хотите отказоустойчивость на случай, если Grid перестал отвечать? Тоже нет: вы не можете запустить несколько реплик и поставить перед ними балансировщик.
Хотите обновить Grid без даунтайма и чтобы тесты, выполняющиеся в данный момент, не упали? Нет, это не про Selenium Grid.
Хотите не держать тысячи Selenium-ов разных конфигураций в памяти, а поднимать их по требованию? Не получится.
Хотите знать, как решить все эти проблемы? Тогда приглашаю вас прочитать эту статью.
*(Мой доклад с таким же названием уже звучал на Heisenbug 2017 Moscow, и, возможно, кто-то из читателей с ним знаком. Под катом — более подробная текстовая версия рассказа об инструменте).

Небольшое отступление, о том как работает Selenium-сервер.

  • Для того, чтобы начать управлять браузером нужно послать запрос create session на Selenium-сервер.
  • В результате на ноде открывается браузер, а к вам возвращается токен sessionId , отправляя который в каждом запросе, вы управляете браузером.
Читайте также:  Какая непосредственная причина развития рдс тест

Окей, а зачем нужен Selenium Grid? Selenium Grid предоставляет единую точку для работы со множеством Selenium-серверов разной конфигурации:

  • он позволяет создавать сессию на свободной ноде, подходящей под ваши критерии фильтрации, например, по версии браузера;
  • хранит информацию о том, какая сессия открыта на какой ноде и проксирует все запросы на целевую ноду, таким образом для клиента нет разницы работать с одной нодой, или с гридом.

Замечательный инструмент, правда?

Но при его использовании мы столкнулись с рядом проблем.

1. Непредсказуемое поведение
Если кратко, то у вас отвалится что захочет и когда захочет, и вы никак не сможете на это повлиять.

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

2. Отсутствие поддержки большого количества нод
При попытке зарегистрировать много нод (а мы хотим много нод), регистрация произойдет, но протестировать приложение во много потоков все равно не получится, так как большая часть тестов упадет.

3. Масштабируемость
Первое, что приходит в голову, когда достигнут предел нод = N на селениум гриде, при котором не страдает стабильность, — это взять два, три, пять, (да хоть десять) гридов, зарегистрировать на каждый по N нод, вкрячить перед всем этим добром какой-нибудь балансировщик и запускать тесты в 10*N потоков. Но нет, Selenium Grid так не работает. Потому что вся информация о нодах и сессиях хранится в памяти у конкретной ноды и не шарится между ними. С этим тесно связана следующая проблема.

4. Отказоустойчивость
Если у вас выключается машина, где находится хаб, то все тесты сразу умирают, потому что у вас нет никаких резервных хабов, на которые могут идти следующие запросы, ибо опять же, все лежит в памяти. И это абсолютно никак не смасштабировать (конечно же, всегда можно переписать пару классов грида, но об этом позже). Слабое место — это Selenium Hub, при его падении ноды становятся недосягаемыми.

5. Отсутствие возможности динамического создания нод с использованием система оркестрации контейнерами
Если для тестирования вам необходимо множество различных конфигураций нод с разными конфигурациями браузеров, то возникает еще одна проблема: весь этот зоопарк занимает довольно много места в памяти. Предположим, у вас: 300 нод с Google Chrome (150GB RAM) + 300 нод с Firefox (150GB RAM) и еще 200 нод какого нибудь Firefox Nightly c магическими плагинами (100GB RAM). 400GB RAM постоянно заняты, плюс хочется эффективно перераспределять ноды в течение дня, скажем, занять все 400GB семью сотнями хромов при тестировании одного сьюта и гибко заменять их при появлении в очереди тестов с другими потребностями.

Для решения этой задачи идеально подойдет Docker, так как он позволяет быстро поднимать контейнер со свежим Selenium и так же быстро его убивать после завершения теста. И так как селениумов нам нужно много, на один железный сервер все это не влезет, возникает потребность в оркестрации контейнеров на кластере. На рынке существует несколько популярных решений для этой задачи, у нас используется Kubernetes. Почему мы выбрали Kubernetes, можно послушать здесь. Стандартными средствами Selenium эту проблему не решить.

6. Невозможно обновить/перезапустить грид без даунтайма
Еще одно следствие хранения сессий в памяти. Не то чтобы это суперкритичный минус, но всё равно неприятный.

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

Известные решения

Grid Router и новая реализация Go Grid Router — хорошее решение, но к сожалению далеко не идеальное. Основная проблема особенность, то что это не замена для Selenium Hub, это еще одна прокси сверху.

Отсюда и название — Grid Router, потому что он управляет не нодами, а гридами, поэтому есть минусы.

  • Попытка создания новой сессии происходит не на гриде со свободными нодами, а на случайном (можно управлять распределением случайной величины при помощи весов). Если на одном из гридов не удалось создать сессию, запрос пойдет на следующий, и так пока не закончатся гриды. Таким образом время создания новой сессии может затягиваться на значительные промежутки времени.
  • Если один из селениум хабов упадет, то вся информация о сессиях будет потеряна, а ноды отключены от сети. Так как до сих пор все взаимодействия идут через хаб и данные о сессиях хранятся в хабе.
  • Довольно трудно добавить еще один хаб в систему, потому что данные о хабах хранятся в xml-файликах и синхронизация с файлами происходит по сигналу операционной системы. Транзакций нет, все плохо.

Selenoid — средство для запуска тестов в docker-контейнерах. При каждом запросе на создание сессии запускается свежий контейнер и при закрытии сессии удаляется. Инструмент замечательный, но есть минусы:

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

Когда мы столкнулись со всеми этими проблемами, мы решили поинтересоваться опытом других компаний. «Яндекс» писал в блоге на Habrahabr о том, что не получается регистрировать много нод и работать с ними, для решения этой проблемы они используют Grid Router. Для наших задач Grid Router не подходит.

«Альфа-Банк» писал о том, что у них все повисает, если grid какое-то время не использовать, и наш опыт это подтверждает — у нас то же самое было регулярно.
Конечно же мы не обделили вниманием github selenium, где нашли несколько issue… Вот пример отношения авторов к происходящему:

Мы поняли, что надеяться нам не на что, и стали сами решать свои проблемы.

Исследование

Мы решили начать с простого пути, задеплоили в kubernetes кластер некоторое количество селениумов, сложили ip в БД и непосредственно в setUp() теста ходили в базу брали оттуда ip, который дольше всех не использовался и запускали тест, нигде не храня sessionId и не блокируя ноды. Так как воркеров с тестами было -role node , указываете где адрес хаба, нода регистрируется, можно пользоваться:

java -jar selenium-server.jar -role node -hub http://127.0.0.1:4444/grid/register

  • On-demand — в конфиг грида нужно добавить докер-образы и информацию о том, какие capabilities они реализуют. Дальше запускаете грид, запрашиваете сессию, нода сама создается в кластере.

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

Читайте также:  Программа для теста разгона оперативной памяти

Источник

Автоматизация тестирования с помощью Selenoid

Многие команды инженеров по тестированию ПО при выполнении автоматизированных тестов отдают предпочтение такому инструменту, как Selenium Grid. Данное решение позволяет получить распределенную среду для параллельного выполнения большого количества тестов. Однако в процессе работы над проектом могут возникать определенные сложности. Их можно избежать, если вместо Selenium Grid использовать Selenoid.

Читайте дальше и вы узнаете об:

  • Особенностях работы с Selenium Grid.
  • Преимуществах и возможностях Selenoid.

ОСОБЕННОСТИ РАБОТЫ С SELENIUM GRID

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

Решение это популярное, но при работе с ним инженеры по автоматизации должны иметь в виду следующие особенности:

  • Длительный процесс развертывания

Для установки Selenium Grid понадобится:

  1. скачать и установить Java Development Kit;
  2. найти и скачать актуальную версию Selenium Server JAR;
  3. скачать необходимые версии веб-драйверов;
  4. распаковать веб-драйвера из архивов;
  5. установить необходимые версии браузеров;
  6. ввести ряд достаточно длинных команд в командную строку.
  • Сложные команды запуска

Вот примеры команд для старта сервера и узлов:

  • Снижение скорости работы

При использовании большого количества нод с разными браузерами хаб начинает работать достаточно медленно.

Важно следить, чтобы версии нод и браузеров были совместимы. Иначе может возникнуть конфликт.

ЧТО МОЖНО ПРЕДПРИНЯТЬ?

Некоторые сложности, например, длительный процесс установки, могут быть преодолены.

Оптимизировать процесс поможет Docker – контейнерная платформа для быстрой сборки, отладки и развертывания приложений.

После создания образа можно переходить к созданию контейнера, который будет содержать все необходимое для работы приложения: библиотеки, системные инструменты, код и среду исполнения.

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

SELENOID КАК АЛЬТЕРНАТИВА

Чем можно заменить Selenium Grid? Достойным вариантом является Selenoid – инструмент, с помощью которого можно быстрее и проще запускать браузеры в Docker-контейнерах. Процесс отличается от аналогичного в Selenium.

Для каждого запроса нового браузера Selenoid запускает новый контейнер и останавливает его после закрытия сессии.

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

Selenoid написан на языке Golang и поддерживает все востребованные браузеры.

SELENOID VS. SELENIUM GRID

Цель использования данных решений одна – создание единой среды для параллельного запуска автотестов. При этом между решениями существует ряд важных отличий. В чем же преимущества Selenoid?

Источник

Параллельный запуск тестов Все стартует в одном окне браузера

  • Авторизуйтесь для ответа в теме

#1 OxanaKIseleva

#2 BabyRoot

В бефоре оставить

#3 OxanaKIseleva

В бефоре оставить

Все сделала, как Вы сказали. Перестало работать вообще)

#4 BabyRoot

У меня вот так работает:

Локально проверял заменой .setWebDriver(driver); на .setWebDriver(new ChromeDriver(options));

#5 OxanaKIseleva

А сделайте так:

У меня вот так работает:

Локально проверял заменой .setWebDriver(driver); на .setWebDriver(new ChromeDriver(options));

Нет, не получилось. Все сделала, как у Вас, а тесты все равно в одном окне браузера шпарит.

Pom настраивать на параллельный запуск надо? Как-то изменять настройки maven-surefire-plugin? У меня настроено только в testng.xml:

Может мой вопрос тупым покажется, но зачем тогда нужен ThreadLocal для параллельного запуска тестов? Или это только Selenide «сам все делает», а если без Selenide, то нужно ThreadLocal использоывать?

Сообщение отредактировал OxanaKIseleva: 14 мая 2020 — 15:42

#6 BabyRoot

У меня parallel=»methods», ну и тредов для начала поставьте 2.

Селенид всё сделает — это я про то, что не надо где-то сохранять все создаваемые драйвера, WebDriverRunner всё сам сохраняет и отслеживает какой открыть, какой закрыть.

#7 OxanaKIseleva

У меня parallel=»methods», ну и тредов для начала поставьте 2.

Селенид всё сделает — это я про то, что не надо где-то сохранять все создаваемые драйвера, WebDriverRunner всё сам сохраняет и отслеживает какой открыть, какой закрыть.

Сделала methods, но теперь проблемы с закрытием driver. Одно окно закрыл остальные висят и тормозят открытие других OWjDRz.jpg A2XnYH.jpg

#8 OxanaKIseleva

Из-за того, что driver не закрывается корректно, решила реализовать так:

Типа закрывать driver после каждого тестового метода. Не знаю, насколько верно. По идее, если Selenide все отслеживает, он это сделать должен был. Вот это я так и не поняла.

С такой реализацией все ок. Но боюсь, что это просто «костыли»(

#9 BabyRoot

Не,не, я ошибся, да надо классы в параллели.

Афтерметод — не надо, оставьте афтер класс. Всё должно работать:

test1 и test2 — в одном потоке, 3 и 4 в другом

Версия селенида какая? обновите на 5.10.0

#10 OxanaKIseleva

Не,не, я ошибся, да надо классы в параллели.

Афтерметод — не надо, оставьте афтер класс. Всё должно работать:

Версия селенида какая? обновите на 5.10.0

Нет. Запустил 2 потока, а тесты в одном окне шпарит.

Тестовый класс для примера:

#11 OxanaKIseleva

Реализацию базового класса оставила, как Вы сказали, аннотации @AfterClass и @BeforeClass. Поменяла testng.xml, заменила classes на methods

Пока заработало, так как надо. Сейчас гоняю в отладчике, ищу, что м б не так. Но вроде работает.

В любом случае, огромное спасибо Вам за помошь и реальные советы.

#12 BabyRoot

Напишите тут для проверки как у вас вывелось:

#13 OxanaKIseleva

Реализацию базового класса оставила, как Вы сказали, аннотации @AfterClass и @BeforeClass. Поменяла testng.xml, заменила classes на methods

Пока заработало, так как надо. Сейчас гоняю в отладчике, ищу, что м б не так. Но вроде работает.

В любом случае, огромное спасибо Вам за помошь и реальные советы.

В итоге, выставила число потоков >2 и о5 25. Возвращаюсь к варианту parallel = «classes» и разбираюсь, что не так

#14 BabyRoot

У меня заработало так —

С Параллель-метод — работает некорректно.

Получил что тесты 1-2 и 3-4 (из разных class name=) работают в разных потоках:

#15 OxanaKIseleva

Ещё раз.

У меня заработало так —

С Параллель-метод — работает некорректно.

Получил что тесты 1-2 и 3-4 (из разных class name=) работают в разных потоках:

Запустила в 2 потока с

все отработало PASSED, но запускается только одно окно браузера, и с ним последовательно работают потоки. А надо параллельно.

Ниже лог из консоли Идеи (3 тестовых класса в 2 потока):

#16 BabyRoot

Вы, наверно устали просто, и не замечаете что у вас открывается 2 окна браузера )) Вы сдвиньте одно окно, под ним будет ещё одно.

По логу всё корректно, всё отработало.

У вас сначала запустились в двух потоках TestClassOne и TwoTestClass, т.к. TwoTestClass имеет только 1 тест, он быстро отработал и закрылся, и запустился ThreeTestClass в другом потоке.

#17 OxanaKIseleva

Вы, наверно устали просто, и не замечаете что у вас открывается 2 окна браузера )) Вы сдвиньте одно окно, под ним будет ещё одно.

По логу всё корректно, всё отработало.

У вас сначала запустились в двух потоках TestClassOne и TwoTestClass, т.к. TwoTestClass имеет только 1 тест, он быстро отработал и закрылся, и запустился ThreeTestClass в другом потоке.

Как бы я хотела, чтобы Вы были правы, но увы. Для теста добавила в каждый тестовый метод добавила Selenide. sleep ( 30000 ) ;

Чтобы тест выполнялся медленнее и можно было отловить открытие окон браузера. Вижу что 2 процесса запустилось, 1 окно открылось. Один тест выполняется в браузере, второй setup() ждет и выполняется только после того, как выполниться другой тест. На скрине видно.

Источник

Поделиться с друзьями
Наши факторы
Adblock
detector