Selenoid — сотни параллельных UI-тестов легко и быстро. Павел Сенин

Предлагаю ознакомиться с расшифровкой доклада 2017 года Павла Сенина «Selenoid — сотни параллельных UI-тестов легко и быстро».

micvac65vuvkclscliuznzlclmw.png

Сегодня я вам расскажу о новом проекте от разработчиков, которые работают в Яндексе, которые понимают толк, как запустить много тысяч тестов параллельно и которые для нас облегчили эту задачу.

hhj4rzxi-wgozyhi22fn1n2t0tk.png

Немного обо мне. Я вошел в IT в 2007-ом году сисадмином, потом работал it-менеджером. Занимался некоторыми проектами из среднего и малого бизнеса. Несколько лет назад перепрофилировался в автоматизатора. И всегда старался заниматься автоматизацией, когда сисадмином работал и когда разработчиком немного работал. Не люблю делать ничего руками, особенно ручные тесты, поэтому я не верю, что можно быть ручным тестировщиком и автоматизатором одновременно. Но это личное.

yw1wsgdp6mu0wwwrodhmpieypzw.png

Сегодня мы посмотрим на конкретном production-проекте, зачем нужен Selenoid и какой профит он приносит. У нас был проект автоматизации достаточно большой по количеству автотестировщиков и по количеству тестов. Это проект, который собрал практически все антипаттерные процессы как тестирования, так и автоматизации. И это было дополнительным стимулом, чтобы применить это в том числе на проекте Selenoid.

Затем мы детально сравним в чем же отличается Selenoid от Selenium Server. Посмотрим, какие у него преимущества перед Selenium Server.

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

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

-mksxiki0hwjdwdcoqyd_rqfj3i.png

Я не могу рассказывать, что это был именно за проект. Но чтобы вы себе представляли, то это примерно, как если взять Outlook и вкладку «Календарь» и усложнить это все раз в десять, и запихать в веб. Это приложение для планирования рабочего времени для иностранных компаний. Это сложнейший UI. Там одновременно было накручено несколько JavaScript-фреймворков самых модных, самых тормозных. Т. е. там такая ситуация, что кликаешь на кнопку, а появляется какое-то действие через 5–10 секунд и это было нормально. Из-за этого тесты были достаточно нестабильные.

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

И одна из самых больших проблем — это неоднородное окружение, т. е. компы автоматизаторов были в основном на Windows 10. Запускались автотесты в облаке. Само приложение работало в другом облаке и поэтому там намешивались задержки и все остальное, что тоже очень плохо сказывалось на стабильности.

Достаточно много автотестов. Сейчас это, наверное, не такая впечатляющая цифра, но т. к. там был применен один из антипаттернов, то эти тесты были длительные. Атомарность там очень часто не соблюдалась и то, что в UI-тестах он длится 5–20 минут — это было частым явлением.

И больше 30 автотестировщиков в команде. Причем команды были распределенные из России, из Канады, из Китая даже.

p-hbxmefrymksx7v1fcsm2cmt6e.png

Как у нас была построена инфраструктура для автоматизации? Здесь показаны машины автотестировщиков c Windows 10. 30 автотестировщиков, 30 машин. Работали мы в Eclipse. Дебажили автотест локально на машине. Потом регрессию запускали через Jenkins, который уже обращался на машины в облаке.

Почему мы дебажили локально, а потом еще пропускали дополнительно в облаке? Потому что локальное окружение и окружение, где запускались браузеры в облаке, оно отличалось. В облаке стоял Windows server 2008 R2, Chrome, FF версии часто отличались. И мы вынуждены были все это перепроверять отдельно на виртуалках, которые стояли в облаке.

Сначала там виртуалок было не такое же количество как автотестеров. Сначала там их было примерно половина — 15 штук. Там стоял на каждом Selenium Server и можно было параллельно запускать тесты.

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

И большие регрессионные тесты запускались на более мощных виртуалках. Для каждого браузере было по несколько виртуалок. И там уже regression jobs прогонялись ночные, которые были длительные, т. е. по несколько часов.

r6skdgsu3_0y0e4ca8lnapfdu6y.png

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

Трудоемкое управление средой. Где-то 30–40 виртуалок. Отдельно этим занималась DevOps-команда из Канады. Там очень большой лаг по времени контакта с ними. Если приходил новый автотестировщик, то нужно было ждать несколько дней, пока появится новая виртуалка. И любая заявка практически выполнялась по несколько дней.

Виртуалки были на Windows. Это требовало профилактических перезагрузок нод. Плюс сам Selenium Server периодически подвисал, плюс браузеры иногда оставались включенными после автотестов. И примерно раз в неделю каждую виртуалку приходилось перезагружать.

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

И регрессионные тесты однопоточные. И так как UI сложный, запуск нескольких браузеров одновременно с тестами приводил к тому, что часто валились тесты из-за потери фокуса. И чтобы хоть как-то распараллелить мы брали несколько виртуалок с Хромом и на них частями запускали тесты.

348lsas0wnjt9a95iymbztwbdo4.png

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


  • Саймон Стюарт рассказал про zalenium. Т. е. обычный Selenium Server запихнули в контейнер, который может управлять другими контейнерами и по запросу поднимать браузер в контейнерах, в том числе может обращаться к облачным провайдерам, которые предоставляют браузеры — BrowserStack и подобные.


  • Те же самые разработчики из Яндекса еще несколько лет назад столкнулись с тем, что Selenium в режиме Hub запущенный тоже не любит большие нагрузки, хотя, казалось бы, это просто прокси своеобразный. И чтобы добиться параллелизации в 1000 тестов, ставили дополнительные Selenium Hub и с дополнительной библиотекой со стороны клиента, у которого запускались тесты. Перебирали доступные Selenium Hub. Было вот такое масштабирование, потому что сам Selenium Hub из коробки не поддерживает масштабирование, он ничего не знает про другие сессии.


  • Вчера был доклад Михаила Подцерковского из Авито. Это разработка из Альфа-Лаборатории. У них есть интересная статья на Хабре. Там можно оценить, насколько сложная инфраструктура, т. е., мне кажется, что один человек это вряд ли потянет. У них Apache Mesos — это одна из инфраструктур управления докеризации. Там они применяли подобную практику, т. е. размножили Selenium Hub. И с помощью разных инструментов учитывали, куда направлять сессии, чтобы распараллелить.


  • Jsonwire Grid. Михаил Подцерковский рассказывал варианты решения от Авито. Чем они все объединяются? Михаил рассказывал, что они берут готовый Selenium Server и пытаются приставить к нему костыли. Все признают, что у Selenium Server есть проблема, что он не оптимально работает при больших нагрузках, у него есть утечки памяти, он зависает. Но вместо того, чтобы решить проблему кардинально, все пытаются к нему подставить какие-то подпорки.


si2cirej-sxhozh9eiyisps4mhc.png

Чем мне понравился Selenoid? Тем, что он эту проблему решает на корню. Т. е. как у нас работают автотесты Selenium Server? Они через ip Selenium Server посылают команды. Selenium Server преобразует их. Он как прокси выступает. Пересылает их в WebDriver определенного браузера, у каждого браузера он свой. И WebDriver управляет браузером.

Как Selenoid себя ведет? Он для автотестов выглядит точно так же. Он полностью совместим с Selenium Server. Вам не нужно менять ни строчки кода в своих автотестах. Вы пишите адрес хоста и все, и запускаете автотесты. Для автотестов все будет то же самое.

А дальше Selenoid автоматом запускает необходимые браузеры в контейнерах. Если вы в Capabilities поставили Chrome 56-ой версии, то он сам найдет образ 56-ой версии, запустит его в контейнере и прогонит там автотесты. И если там что-то зависло, допустим, в браузере, в приложении и в итоге браузер не закрылся автоматом, то он по умолчанию через минуту сам убьет браузер с контейнером. Это очень удобно. Не нужно думать про зависшие браузеры.

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

nzhmaxfo3wsccl8ybcrpbv8m1sg.png

Как мы перешли на Selenoid? У нас остались те же самые машины разработчиков. Мы на них ничего не меняли. Мы подняли виртуалку с Линуксом, в котором был установлен Selenoid: Selenoid и Selenoid UI. Там было два контейнера. Selenoid UI — это удобная графическая консоль для контроля работы за Selenoid. У нас только поменялся адрес хоста, на котором мы запускаем тест.

И, соответственно, была еще одна отдельная виртуалка. Она была гораздо мощнее. В ней поднимались контейнеры с браузерами. Там были закачены образы необходимых браузеров для работы. И по запросу от Selenoid там они поднимались.

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

И плюс регрессия тоже запускалась через Selenoid. Регрессионные тесты запускались в тех же контейнерах в чистых. Регрессионные тесты запускались в одинаковой среде. Т. е. дебаг, отладка, регрессия запускались на одинаковом окружении. Это нам позволило достичь стабильности, исключить все ошибки из окружения. И также мы гоняли тесты на IE, но реже. Его нельзя докеризовать. И приходилось его запускать на отдельной виртуалке, как и раньше.

z-ejjo3cpwrmqubzsrzxlcsl6ck.png

Собрал все плюсы, которые мы получили основные.


  • Мы получили одинаковое окружение.


  • Мы добились хорошей утилизации ресурсов, т. е. нам не нужно 30 виртуалок для автотестеров. У нас есть одна большая виртуалка, которая выдерживает нужные нам нагрузки. Мы значительно сократили потребление ресурсов, CPU в два раза уменьшили, а память еще больше.


  • Мы смогли довести одновременных автотестов до 30 потоков. Selenoid позволяет и сотни потоков делать, но мы столкнулись с тем, что наше приложение настолько медленное, что 5–10 одновременно запущенных тестов устраивали DDoS-атаку, и оно начинало тормозить. Если у вас встанет задача — убыстрить автотесты, то нужно еще подумать о перфомансе самого приложения. Потому что JavaScript не дает расслабиться.


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


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


jgvhgppynoraugjqmlf0h-9hsnq.png

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

ntnutpsf0fib_-12v2tw6dblk3a.png

Сравним Selenoid и Selenium Server.

9xktz3bpw2l1e97mak-teyjhwj8.png

Я покажу, что:


  • Selenoid гораздо проще и быстрее устанавливается, чем Selenium Server.


  • С ним удобнее управлять браузерами.


  • На порядок более легкое масштабирование количества параллельных автотестов.


  • Имеет очень удобный UI и логирование.


  • Имеет дополнительные фишки, например, очереди. Если у вас на хост пришло слишком много автотестов одновременно, и хост не может их переработать, то Selenoid ставит их в очередь. И будет их пропускать по очереди, как только какие-то тесты уже завершатся.


fxgls2edspktzwksdhrsgnth5pu.png

Как ставится Selenium Server? Вам нужна Java и браузеры нужных версий. Все это нужно распаковать. Есть даже, по-моему, платные курсы специальные, как Selenium Server поставить.

1vuhbmskv4fmh7fcqcllugatudu.png

Как ставится Selenoid? Ребята упростили задачу. Тут практически докер не нужно знать никакой. Вам нужно Линукс-машина, с установленным докером. Докер ставится легко. Это гуглится элементарно.

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

of5uvgmzo-h8h_b8pxlffbfgv-o.png


  • Обновление браузера в нашей предыдущей конфигурации, т. е. на 30 виртуалках — это была боль. Кто-то обновлял, кто-то забывал. Баги были связаны еще с тем, что в одной версии работает, в другой не работает какой-то функционал.


  • Следить надо было за соответствием WebDriver и определенной версии браузера.


  • Иногда очень трудно поставить Chrome, Firefox в систему с разными версиями. Обычно в production делают отдельные виртуалки для разных версий, чтобы получить стабильность запуска.


uen5vbb_8olplo1awoy-0khecrq.png

Как у Selenoid обстоят дела с обслуживанием браузеров?

У вас уже есть готовые контейнеры, вам не нужно ломать голову про соответствие WebDriver и браузера.

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

Для каждого теста всегда есть новый браузер, как будто только что установленный в ОС.

pdx1zpk09_gl7ofqhzdnjgfu-0w.png

Сами браузеры задаются через config.json. Это один файл, который лежит рядом с утилитой Configuration Manager. Когда вы в первый раз стартуете ее, она автоматом генерирует JSON, туда прописывает Chrome, Firefox, Opera двух последних версий. Но вы всегда можете через эту утилиту или прямо руками залезть и поменять на необходимые версии браузеров. В JSON указывается тип браузера, версия, ссылка на образ контейнера. Мы получили удобную работу с браузерами.

gqgrovhxldfy_wzmt5udcrwujdc.png

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

И не только из-за ховера, про который я упомянул, из-за фокуса, а потому что не будет стабильности. Обычно берут один хост на отдельную виртуалку с одним браузером и там гоняют: только тесты для Firefox, только для Chrome и т. д. И обычно Selenium не держит больше 10–20 сессий браузеров на одном хосте. Он потребляет много памяти и нестабильно работает.

pszihs9hxynaecwm6msljh01zh8.png

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

Эмпирически установлено, что обычно на один браузер идет потребление одного ядра CPU и 200–500 MB памяти. Если вы даже в Windows запустите Chrome, вы заметите, что, открыв несколько сайтов, в оперативной памяти он где-то 500 MB выжирает. И если на сайте есть JavaScript, то он будет занимать 20% процессорного времени на 4-ядерной машине.

Плюс по умолчанию в контейнерах встроена поддержка tmpfs, т. е. браузеры стартуют и линкуют свою временную папку в оперативную память. Когда браузер начинает открывать сайты, он сохраняет много временных файлов, cookies, изображения, т. е. все вспомогательные файлы. И если эта работа происходит с дисковой системы, то это очень сильно тормозит производительность браузера. Здесь все это в tmpfs складывается. И потом контейнер убивается.

И как я уже говорил, есть тайм-аут неактивности в минуту по умолчанию. Вы можете этот тайм-аут изменить. Через минуту неактивности контейнер убивается.

wqphsmhc1zirdpkafetai5wxw0c.png

Также Selenium умеет масштабироваться на уровне балансировщика, т. е. вы тот же Selenium Server запускаете с ключиком Hub. Он работает в режиме упрощенного прокси. И перенаправляет запрос уже на конкретные ноды.

С этим есть проблемы. В том же Авито пришло множить Hub, потому что он не выдерживает большой нагрузки. У них там несколько сотен параллельных автотестов, скоро, скорее всего, это количество дойдет до 1 000. И Selenium Hub просто умирает под такой нагрузкой. Изначальная проблема в библиотеке Java — Jetty, которая работает как прокси-сервер внутри. На Stackoverflow больше 5 700 вопросов о проблемах с ней. Я не знаю, почему в Selenium Server ее не заменили. Она из года в года остается там. И приносит много страданий.

Selenium Server сделали универсальным. Там работает UI-консоль. Она его нагружает дополнительно, снижает стабильность.

Плюс Selenium Hub не поддерживает отдельное логирование. Он вам будет слать логи вперемешку со всеми сессиями. Это нужно будет отдельно обрабатывать.

7jeuid3jdx32jyly-zqsq1vnabc.png

Как Selenoid масштабируется? Вот так он примерно работает в Яндексе. Он держит нагрузку 5 000 параллельных сессий браузеров в 5 датацентрах. Запускает браузеры в Linux и в Windows.

Selenoid может не только контейнеры запускать, но и работать как классический Selenium Server в Windows.

Как этого в Яндексе добились? Они используют специальный балансировщик, который перекидывает запросы случайным образом на Go Grid Router. Это замена Selenium Hub. Те же разработчики из Яндекса написали отдельное приложение, которое занимается проксированием запросов. Приложение получилось очень маленьким и очень мощным, т. е. выдерживает огромные нагрузки. 5 000 параллельных браузеров обеспечивает 10 Go Grid Router. И Go Grid Router случайно раскидывает сессии на мощные хосты, где уже поднимается Selenoid и контейнеры с браузерами.

По-моему, Михаил говорил, что на Авито они от этого отказались, потому что они случайно раскидываются. Но на самом деле, если у вас хостов до 10, то это случайное раскидывание не приводит к нагрузке какого-то одного хоста. И тем самым мы добиваемся, что Go Grid Router ничего не знает про сессии, не надо ему никакой базы данных. Это маленький бинарник, который очень эффективно раскидывает сессии.

И, соответственно, мы используем несколько Go Grid Router. Мы можем распараллелить до очень хороших масштабов.

ndaqs3iddd2ydtzdfpv1g096myi.png

Ребята из Яндекса тоже, как и ребята из Авито, залезли в исходники Selenium Server и ужаснулись. Ребята из Авито просто закрыли. А ребята из Яндекса переписали на Golang тот же Selenium Server. Там порядка полторы тысяч строчек кода получилось. И добавили функционал поднятия контейнеров и кучу других удобных фич.

Это очень маленький исполняемый файл. И там, где Selenium Server потребляет 500 MB оперативной памяти, если у вас порядка 10 сессий открыто, то Selenoid потребляет 50–60 MB, т. е. в 10 раз меньше.

t-2xsx8ctzxzihjfg-oftnuiyos.png


  • Быстрая установка.


  • Удобная работа с браузерами.


  • Легкое масштабирование.


gim9m05o6rk80hgl85vjnap8jfo.png

Вот это Selenium Grid консоль.

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

lgkjgaspedh32su16rmsiyomf1q.png

Вот так выглядит Selenoid консоль. Это основная часть, где самая полезная информация указывается.v5nxeh9ydb0gccowyutcg9hy1ey.png

Здесь показывается текущая нагрузка на хост с Selenoid.

Что значат эти цифры? 80% — это значит, что хост загружен на 80%, т. е. по количеству сессий, который он может одновременно через себя пропустить. В данном случае тут маломощный хост, который может только 5 сессий держать. И на нем запущено 4 сессии одновременно. И 4 + 0 — это значит, что ни одной сессии нет в очереди. И сейчас 4 сессии запущено с Firefox. Как видите, можно спокойно запускать Chrome, Firefox, Opera одновременно и они друг другу совершенно не будут мешать. Отдельно вынесеные цифры с очередью.

ohf0cthp5cndem4aa-_mivh6uoc.png

Когда тесты запущены, появляются иконки с браузерами. Вы можете щелкнуть на эту иконку. Тут написано название браузера, версия, внутреннее разрешение экрана. В этой же консоли у вас открывается окно с VNC, и вы можете смотреть то, что там сейчас происходит. Т. е. вы можете остановить тест во время дебага, открыть консоль разработчика и посмотреть XPATH и CSS-запросы и т. д.

wohk5q_wmrpygfsj1bsd10ofvge.png

Также можно смотреть логи по каждому браузеру, по каждой сессии отдельно. Здесь у вас не будет такого как в Selenium Hub, когда логи идут вперемешку. Вы также можете в режиме дебага остановить и параллельно смотреть в UI-консоли, что внутри браузера происходит и тут же смотреть логи, как работает Selenoid. В данном случае видим что это Chrome 58-ой версии и id запущенной сессии.

В том числе мы получили удобный UI и добились удобного логирования.

ntbkrrqbrdgvij2jsahndqyd-w8.png

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

Плюс в Selenoid есть очереди, про которые я уже говорил.

Можно отдельно для каждого контейнера устанавливать лимиты на CPU и на RAM. Если у вас есть прожорливое приложение, где JavaScript ненасытный и потребляет очень много ресурсов, можно для стабилизации ограничить потребление этих ресурсов контейнером. Это очень удобно в production.

cp74exxuy6pnbly39kfgeqmgbz0.png

Мы получили очереди и гибкие элементы.

ukfp7levspvaas4xujkou064n1a.png

Но это еще не все. Есть еще дополнительные преимущества.


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


  • По умолчанию используются образы разработчиков Selenoid, но вы можете использовать готовые образы. Есть официальные образы от Selenium с браузерами. Или вы можете создать свой образ, если по политике безопасности вам не разрешают лезть в общедоступные репозитории. Внутри образа у вас должен быть браузер с WebDriver. Должен быть установлен X-сервер, чтобы браузер при запуске думал, что он запущен на реальном экране.


  • Поддержка централизованного логирования. Selenoid позволяет не просто смотреть отдельные логи браузера. У него есть специальный адрес в строке. Если туда обращаться, то он возвращает JSON с подобной статистикой того, что сейчас происходит на хосте. Это очень удобно применять для живого анализа того, что происходит. Можно подключить graphite, Grafana. И очень легко получать статистику, и выводить на больших экранах, и показывать текущую ситуацию. Например, отслеживать перезагрузку какого-нибудь хоста или какие-то аномалии.


  • И очень удобная штука — это задание разрешения экрана прямо через код автотестов, т. е. не разрешение самого браузера, с каким он отроется, а именно экрана, чтобы тестировать в том числе мобильные устройства. А именно, когда вы делаете узкий экран, эмулируете экран мобильника, тоже можно запускать и дополнительно проверять тесты.


  • И новая фича появилась недавно, буквально неделю назад. Это встроенная видеозапись тестов, т. е. подгружается специальный контейнер по умолчанию, который по VNC, если вы включили capability специальный, он в одно место складывает видеозапись прохождения автотестов. Но нужно понимать, что это очень грузит хост и нужно использовать только в режимах отладки, потому что по умолчанию Selenoid запускается без поддержки VNC и поддержки видеозаписи, чтобы максимально утилизировать доступные ресурсы для более стабильного запуска автотестов и прохождения.


На этом закончим сравнение подробное.

brvqlzzejf0en5f_hdy2-xwmzje.png

Пару слов, почему именно Docker используется. Это не хайп.

mzzmbpb_lywpebvt1jbkn-6zbkg.png

У нас слева Hypervisor, т. е. классическая виртуализация железа. Справа у нас Docker. Hypervisor эмулирует железо, поэтому виртуальная машина должна внутри себя содержать операционную систему с драйверами, которые поддерживают это виртуальное железо. Например, если запускается Windows, то она где-то минимум гигабайт потребляет на свои нужды, в оперативной памяти обычно вообще два гигабайта потребляется. И такой кусок надо отдать каждой виртуальной машине. И даже если у вас одинаковые зависимости у используемого приложения, все равно это все будет изолированно в каждой виртуальной машине дублироваться.

Docker эмулирует операционную систему. Я говорю упрощенно. Ему не нужно внутри контейнеров содержать операционную систему с драйверами, которые поддерживают железо. Это все уже на уровне Docker (контейнеризации) разруливается. И если вы используете какие-то одинаковые зависимости, то они также не дублируются. Это очень хорошо экономит место на дисках. Вам не надо дублировать лишний раз информацию.

9fw-oh9fc8vtvend2a83avvv8w4.png


  • Почему Linux? Ведь, казалось бы, IE не работает там, но если посмотреть, то основные браузеры — это Chrome, Firefox и Opera, а IE, Safari уже не так популярны. В том же Яндексе, хоть и следят хорошо за качеством работы приложения, но на IE и Safari они оставляют меньше внимания. Потому что тот же самый Safari нельзя виртуализовать, т. е. им приходится автотесты запускать на реальном железе. А от IE многие страдают. Edge работает не лучше, плюс Edge пока не поддается контейнеризации.


  • Нет потери фокуса при запуске параллельный тестов. Фокус — это когда мы наводите на какой-то элемент мышкой, и он меняет свои свойства. И по этим свойствам уже автотест кликает, т. е. по этому элементу. В этом случае окно браузера должно быть в фокусе. А если у вас на одном хосте несколько браузеров запущено, то часто возникает ситуация, что вы навели мышку, вроде бы hover появился и в то же время другой браузер тоже работает, и фокус переместился на него. И автотест, соответственно, падает, потому что снова поменялось свойство элемента. Здесь у нас один браузер в одном контейнере. Он ничего не знает про другие браузеры и таких проблем нет.


  • Это нам дает еще одно преимущество — это чистая ОС у автотестировщика и разработчика. Мы столкнулись с тем, что если вы используете Selenoid, то очень просто заставить разработчика запускать автотесты. Т. е. раньше там надо было поднять что-то дополнительно, чтобы запустить, а сейчас не нужны никакие веб-драйвера, просто автотест запускается сразу в Selenoid.


  • На одном хосте возможно любое сочетание браузеров. Нам не нужно плодить отдельный хост под каждый браузер.


  • И браузер стартует очень быстро, потому что контейнеры стартуют очень быстро, там готовый образ практически мгновенно запускается.


  • И как я уже говорил, мы получаем значительную экономию вычислительных ресурсов хоста.


vqimx71gytty17hcyghyjzs_cv0.png

Selenoid написан на Golang, поэтому его компилируют под все платформы, в том числе и под Windows. К нему прописывается конфигурация с JSON, в котором будет написано, что используется IE и ключ, что мы не используем режим контейнеризации.

И там есть еще пара магических штук, которые позволяют стабилизировать запуски на IE. Это обертка веб-драйвером, которая запускает каждый IE в отдельном виртуальном окне. Т. е. у Windows есть поддержка виртуальных окон и это практически убирает проблему с потерей фокуса. Можно на одном хосте более-менее 5–10 штук запускать.

И есть специальный Selenium capabilities, который можно использовать. На это есть ссылка в презентации. Там очень хорошая статья, там подробно про это написано. Он работает как экзешник. И вы получаете однородную среду для запуска автотестов. Мы до этого не дошли, но это возможно, в Яндексе это используют.

yksk4jxqplycbtm5bcyxtgldmak.png

У нас есть время для демо. Что в демо будет?

Я покажу:


  • Установку Selenoid.


  • Запуск параллельных автотестов.


  • Подключение по VNC вовнутрь контейнеров с браузером.


  • Просмотр «живых» логов по отдельному браузеру.


  • Видеозапись тестов.


w37ccjcf52pqjf93bt9h2kzvfme.png

Установка состоит из трех основных шагов:


  • Мы скачиваем утилиту Configuration manager.


  • С помощью ее запускаем Selenoid.


  • И запускаем Selenoid-UI, графическую консоль.


Я здесь сейчас все буду делать на одном хосте. А в production, чтобы увеличить интенсивность прохождения тестов, Selenoid и Selenoid-UI разносят на разные хосты, чтобы они друг другу не мешали при больших нагрузках.

Демо начинается с 43 минуты.

Есть у нас виртуалка с Линуксом. Ubuntu 16.04.3 — это одна из последних стабильных версий. Я думаю, что ни у кого не возникнет проблем с установкой. Проверяем, что там установлен Docker из последних версий. И это все, что нужно вам для старта.

Проверяем, что у нас никакие контейнеры не запущены сейчас, что сейчас нет никаких фокусов. И проверяем, что не закачены никакие образы заранее. Образов у нас нет. У нас чистый Docker в системе.

Мы заходим на github.com/aerokube. Aerokube — называется у них командный репозиторий. Обратите внимание, что это все проекты, относящиеся к Selenoid. Т.е. это очень мощный и продуманный продукт.

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

Копируем адрес, через wget закачиваем этот бинарник и называем его «cm». Бинарник весит всего лишь 12 MB. Качается он очень быстро. Закачали бинарник. Файл у нас назван «cm». И не забываем еще добавить права на запуск этого бинарника.

Теперь стартуем бинарник с ключом «selenoid start». И говорим, что хотим, чтобы он поддерживал контейнеры с VNC.

Он автоматом запускается. Видит, что он запущен в первый раз, что никаких образов нет, никаких контейнеров с браузером в Selenoid нет. Он сам за вас все качает. Это занимает примерно минут 10. Я тут убыстрил видео.

Все, он закачал. И автоматом запустил Selenoid, т. е. сейчас запущен у нас контейнер с Selenoid. Мы сейчас это проверим. Мы проверяем, что у нас закачены все образы вместе с Firefox, образ с видеорекордером — это новая фича Selenoid, с Opera, с самим Selenoid. Сам образ Selenoid весит всего 13 MB. Но контейнеры, как обычно, в распакованном виде весят порядка 700 MB. И проверяем, что у нас как раз запущен контейнер с Selenoid. И он работает автоматом, смотрит порт »4444». Это стандартный порт Selenium Server. Тут не забудьте еще проверить на своей машине файрвол.

И проверяем JSON-файл, который у нас сгенерировался, с помощью Configuration manager. Мы видим, что у нас 62.0 версия и плюс 61.0 Chrome, и 49.0 Firefox. И тут мы замечаем, что там нет поддержки tmpfs. Мы запускаем просто «configure --help». Он показывает нам все команды доступные у Selenoid. Т. е. есть команда-ключ, которая позволяет добавить поддержку tmpfs. Мы, соответственно, рестартуем просто с дополнительным ключом «tmpfs 256 --force». Force указываем, чтобы он принудительно перезапустился. Тут даже не надо особо документацию смотреть. Она уже, можно сказать, встроена в саму утилиту.

Он еще раз проверяет на всякий случай актуальность образов с браузерами. Генерирует новый JSON

© Habrahabr.ru