Примечание: данная статья является переводом на русский язык оригинальной статьи «DevOps tools are not only for DevOps. Building test automation infrastructure from scratch». Однако все иллюстрации, ссылки, цитаты и термины сохранены на языке оригинала, чтобы избежать искажения смысла при переводе на русский язык. Желаю вам приятного изучения!
В настоящее время специальность DevOps является одной из наиболее востребованных в IT-индустрии. Если вы откроете популярные сайты по поиску работы и зададите фильтр по зарплатам, то увидите, что вакансии, связанные с DevOps, находятся в начале списка. Однако важно понимать, что это в основном относится к позиции ‘Senior’, что подразумевает, что кандидат обладает высоким уровнем навыков, знанием технологий и инструментов. К этому также прилагается высокая степень ответственности, связанная с бесперебойной работой production. Однако мы стали забывать, что такое DevOps. Изначально это не был какой-то конкретный человек или департамент. Если поискать определения этого термина, то мы найдем много красивых и правильных существительных, таких как методология, практики, культурная философия, группа концептов и так далее.
Моя специализация – инженер по автоматизации тестирования (QA automation engineer), но я считаю, что она не должна быть связана только с написанием авто-тестов или разработкой архитектуры тестового framework. В 2020 году знания инфраструктуры автоматизации также необходимы. Это позволяет организовать процесс автоматизации самостоятельно, начиная от запуска тестов и заканчивая предоставлением результатов всем заинтересованным лицам в соответствии с поставленными целями. В результате чего, навыки DevOps являются обязательным фактором для выполнения данной работы. И все это хорошо, но, к сожалению, есть проблема (spoiler: данная статья делает попытки упростить это проблему). Она заключается в том, что DevOps – это сложно. И это очевидно, ведь компании не станут платить много за то, что легко сделать… В мире DevOps большое количество инструментов, терминов, практик, которыми нужно овладеть. Особенно это тяжело дается в начале карьеры и зависит от накопленного технического опыта.
Источник: http://maximelanciauxbi.blogspot.com/2017/04/devops-tools.html
Тут мы, пожалуй, завершим с вводной частью и сфокусируемся на цели данной статьи.
О чем эта статья
В этой статье я собираюсь поделиться моим опытом построения инфраструктуры автоматизации тестирования. В интернете можно найти много источников информации о различных инструментах и как их использовать, но я бы хотел рассмотреть их исключительно в контексте автоматизации. Я полагаю, что многим инженерам по автоматизации знакома ситуация, когда разработанные тесты, кроме вас самих, никто не запускает и не заботится об их поддержке. В результате чего тесты становятся устаревшими и приходится тратить время на их актуализацию. Опять же в начале карьеры это может быть довольно сложной задачей: грамотно решить, какие инструменты должны помочь устранить данную проблему, как их выбрать, настроить и поддерживать. Некоторые тестировщики обращаются за помощью к DevOps (людям) и, будем честными, такой подход работает . Во многих случаях это может быть единственным вариантом, так как у нас отсутствует видимость всех зависимостей. Но, как мы знаем, DevOps – очень занятые ребята, ведь они должны думать об инфраструктуре всей компании, deployment, мониторинге, микросервисах и о других подобных задачах в зависимости от организации/команды. Как это обычно бывает, автоматизация не является приоритетом. В таком случае мы должны попытаться сделать все возможное с нашей стороны от начала и до конца. Это уменьшит зависимости, ускорит рабочий процесс, усовершенствует наши навыки и позволит увидеть более широкую картину происходящего.
В статье представлены наиболее востребованные и популярные инструменты и показано, как их использовать для пошагового построения инфраструктуры автоматизации. Каждая группа представлена инструментами, которые были проверены на личном опыте. Но это не значит, что вы должны использовать то же самое. Сами инструменты не важны, они появляются и устаревают. Наша инженерная задача – понимание базовых принципов: зачем нам нужна эта группа инструментов и какие рабочие задачи мы можем с их помощью решить. Поэтому в конце каждой секции я оставляю ссылки на аналогичные инструменты, которые, возможно, используются в вашей организации.
Чего в этой статье нет
Еще раз повторю, что статья не о конкретных инструментах, поэтому тут не будет вставок кода из документации и описания конкретных команд. Но в конце каждой секции я оставляю ссылки для детального изучения.
Это сделано по причине того, что:
- этот материал очень легко найти в различных источниках (документация, книги, видео курсы);
- если мы начнем углубляться, то придется написать 10, 20, 30 частей данной статьи (тогда как в планах 2-3);
- я просто не хочу тратить ваше время, так как, возможно, вы хотите использовать другие инструменты для достижения тех же целей.
Практика
Мне бы очень хотелось, чтобы этот материал был полезен для каждого читателя, а не просто был прочитан и забыт. В любом изучении практика является очень важной составляющей. Для этого я подготовил GitHub-репозиторий с пошаговым руководством как сделать все с нуля. Также вас ждет домашняя работа, чтобы быть уверенным, что вы бездумно не скопировали строчки выполняемых команд
План
Структура каждой секции
Для поддержания повествования в наглядном виде, каждая секция описана по следующему плану:
- краткое описание технологии,
- ценность для инфраструктуры автоматизации,
- иллюстрация текущего состояния инфраструктуры,
- ссылки для изучения,
- аналогичные инструменты.
1. Локальный запуск тестов
Краткое описание технологии
Это всего лишь подготовительный шаг для запуска демонстрационных тестов локально и для проверки, что они успешно проходят. В практической части используется Node.js но язык программирования и платформа также не важны и можно использовать те, что используются в вашей компании.
Однако в качестве инструментов автоматизации я рекомендую использовать Selenium WebDriver для web-платформ и Appium для Android-платформы соответственно, так как на следующих шагах мы будем использовать Docker-образы, которые заточены на работу конкретно с этими инструментами. Более того, ссылаясь на требования в вакансиях, эти инструменты наиболее востребованы на рынке.
Как вы могли заметить, мы рассматриваем только web и Android-тесты. К сожалению, IOS – совершенно другая история (спасибо Apple). Я планирую продемонстрировать решения и практики, связанные с IOS, в следующих частях.
Ценность для инфраструктуры автоматизации
С точки зрения инфраструктуры локальный запуск не несет никакой ценности. Вы только проверяете, что тесты работают на локальной машине в локальных браузерах и симуляторах. Но в любом случае это необходимая отправная точка.
Иллюстрация текущего состояния инфраструктуры
Ссылки для изучения
Аналогичные инструменты
- любой язык программирования, который вам нравится, в связке с Selenium/Appium — тестами;
- любые тесты;
- любой тест-раннер.
2. Системы контроля версий (Git)
Краткое описание технологии
Ни для кого не будет большим открытием, если я скажу, что система контроля версий – чрезвычайно важная часть разработки как в команде, так и индивидуально. Опираясь на различные источники, можно с уверенностью сказать, что Git является наиболее популярным представителем. Система контроля версий дает множество преимуществ, таких как обмен кодом, хранение версий, восстановление на предыдущие ветки, мониторинг проектной истории, бэкапы. Мы не будем обсуждать каждый пункт в деталях, так как я уверен, что вы с этим хорошо знакомы и используете в повседневной работе. Но если вдруг нет, то я рекомендую приостановить чтение данной статьи и как можно скорее восполнить данный пробел.
Ценность для инфраструктуры автоматизации
И тут вы можете задать резонный вопрос: «Зачем он нам рассказывает о Git? Все это знают и используют как для кода разработки, так и для кода авто-тестов». Вы будете абсолютно правы, но в этой статье мы говорим об инфраструктуре и данная секция играет роль превью для секции 7: «Инфраструктура как код (IaC)». Для нас это означает, что вся инфраструктура, включая тестовую, описывается в виде кода, соответственно мы к ней тоже можем применить системы версионирования и получить аналогичные преимущества как для кода разработки и автоматизации.
Мы рассмотрим IaC более детально на шаге 7, но даже сейчас можно начать использовать Git локально, создав локальный репозиторий. Общая картина будет расширена, когда мы добавим к инфраструктуре удаленный репозиторий.
Иллюстрация текущего состояния инфраструктуры
Ссылки для изучения
Аналогичные инструменты
3. Контейнеризация (Docker)
Краткое описание технологии
Для демонстрации того, как контейнеризация поменяла правила игры, давайте отправимся на несколько десятилетий в прошлое. В те времена люди приобретали и использовали серверные машины для запуска приложений. Но в большинстве случаев необходимые требуемые ресурсы для запуска не были известны заранее. В результате чего компании тратили деньги на покупку дорогих мощных серверов, но часть этих мощностей не была полностью утилизирована.
Следующим этапом эволюции стали виртуальные машины (VM), которые решили проблему траты средств на неиспользуемые ресурсы. Эта технология позволила запускать приложения независимо друг от друга внутри одного сервера, выделяя полностью изолированное пространство. Но, к сожалению, любая технология имеет свои недостатки. Запуск VM требует полноценной операционной системы, которая потребляет CPU, RAM, хранилище и, в зависимости от OS, нужно учитывать расходы на лицензию. Эти факторы влияют на скорость загрузки и усложняют переносимость.
И вот мы подошли к контейнеризации. И снова данная технология решила предыдущую проблему, так как контейнеры не используют полноценную OS, что позволяет освободить большое количество ресурсов и предоставляет быстрое и гибкое решение для переносимости.
Конечно, технология контейнеризации не является чем-то новым и впервые была представлена в конце 70-х. В те времена проводилось много исследований, наработок, и попыток. Но именно Docker адаптировал эту технологию и сделал ее легкодоступной для масс. В наше время, когда мы говорим о контейнерах, в большинстве случаев мы имеем ввиду Docker. Когда мы говорим о Docker-контейнерах, мы подразумеваем Linux-контейнеры. Мы можем использовать Windows и macOS-системы для запуска контейнеров, но важно понимать, что в таком случае появляется дополнительная прослойка. Например, Docker на Mac незаметно запускает контейнеры внутри легковесной Linux VM. Мы еще вернемся к этой теме, когда будем обсуждать запуск Android-эмуляторов внутри контейнеров, так так здесь появляется очень важной нюанс, который необходимо разобрать более подробно.
Ценность для инфраструктуры автоматизации
Мы выяснили, что контейнеризация и Docker – это круто. Давайте посмотрим на это в контексте автоматизации, ведь каждый инструмент или технология должны решать какую-либо проблему. Обозначим очевидные проблемы автоматизации тестирования в контексте UI-тестов:
- огромное количество зависимостей при установке Selenium и в особенности Appium;
- проблемы совместимости между версиями браузеров, симуляторов и драйверов;
- отсутствие изолированного пространства для браузеров/симуляторов, что особенно критично для параллельного запуска;
- тяжело управлять и поддерживать, если необходимо запустить 10, 50, 100 или даже 1000 браузеров одновременно.
Но поскольку Selenium является самым популярным инструментом автоматизации, а Docker – самым популярным инструментом контейнеризации, то ни для кого не должно быть сюрпризом, что кто-то попытался их объединить, чтобы получить мощный инструмент для решения вышеупомянутых проблем. Рассмотрим такие решения более подробно.
Selenium grid in docker
Этот инструмент является самым популярным в мире Selenium для запуска нескольких браузеров на нескольких машинах и управления ими из центрального узла. Для запуска необходимо зарегистрировать как минимум 2 части: Hub и Node(s). Hub – это центральный узел, который получает все запросы от тестов и распределяет их по соответствующим Nodes. Для каждого Node мы можем настроить конкретную конфигурацию, например, указав нужный браузер и его версию. Однако нам все еще необходимо самим позаботиться о совместимых драйверах для браузеров и установить их на нужные Nodes. По этой причине Selenium grid не используется в чистом виде, за исключением тех случаев, когда нам нужно работать с браузерами, которые нельзя установить на Linux OS. Для всех остальных случаев значительно гибким и правильным решением будет использование Docker-образов для запуска Selenium grid Hub и Nodes. Такой подход сильно упрощает управление узлами, так как мы можем выбрать нужный нам образ с уже установленными совместимыми версиями браузеров и драйверов.
Несмотря на негативные отзывы о стабильности работы, особенно при запуске большого числа Nodes параллельно, Selenium grid все еще остается самым популярным инструментом для параллельного запуска Selenium-тестов. Важно отметить, что в open-source постоянно появляются различные доработки и модификации данного инструмента, которые борются с различными узкими местами.
Selenoid for Web
Этот инструмент является прорывом в мире Selenium, так как он работает сразу из коробки и сделал жизнь многих инженеров по автоматизации значительно проще. Прежде всего, это не очередная модификация Selenium grid. Вместо этого разработчики создали абсолютно новую версию Selenium Hub на языке Golang, что в связке с легковесными Docker-образами для различных браузеров дало толчок в развитии автоматизации тестирования. Более того, в случае Selenium Grid мы должны определить все требуемые браузеры и их версии заранее, что не является проблемой, когда работа идет только с каким-то одним браузером. Но когда речь идет о нескольких поддерживаемых браузерах, то Selenoid – это решение номер один, благодаря функции ‘браузер по требованию’. Все, что от нас требуется, это заранее выгрузить нужные образы с браузерами и обновить файл конфигурации, с которым взаимодействует Selenoid. После того как Selenoid получит запрос от тестов, он автоматически запустит нужный контейнер с нужным браузером. Когда тест завершится, Selenoid отставит контейнер, тем самым освободив ресурсы для следующих запросов. Такой подход полностью устраняет известную проблему ‘деградации узлов’, что мы часто встречаем в Selenium grid.
Но, увы, Selenoid все еще не серебряная пуля. Мы получили функцию ‘браузер по требованию’, но функция ‘ресурсы по требованию’ все еще не доступна. Для использования Selenoid мы должны развернуть его на физическом железе или на VM, что означает, что мы должны заранее знать, сколько ресурсов необходимо выделить. Я полагаю, это не проблема для маленьких проектов, которые запускают 10, 20 или даже 30 браузеров параллельно. Но что если нам нужно 100, 500, 1000 и больше? Не имеет никакого смысла поддерживать и платить за такое количество ресурсов постоянно. В секции 5 и 6 данной статьи мы обсудим решения, которые позволяют масштабироваться, тем самым значительно снижая расходы компании.
Selenoid for Android
После успеха Selenoid в качестве инструмента для web-автоматизации, люди хотели получить что-то подобное для Android. И это свершилось – Selenoid был выпущен с поддержкой Android. С высокоуровневой пользовательской точки зрения принцип работы аналогичен web-автоматизации. Единственное отличие заключается в том, что вместо контейнеров с браузерами Selenoid запускает контейнеры с Android-эмуляторами. На мой взгляд, на сегодняшний момент это самый мощный бесплатный инструмент для запуска Android-тестов параллельно.
Мне бы очень не хотелось говорить о негативных сторонах данного инструмента, так как он действительно мне очень нравится. Но все же тут присутствуют те же недостатки, относящиеся и к web-автоматизации, связанные с масштабированием. В дополнение к этому нужно рассказать о еще одном ограничении, которое может стать неожиданностью, если мы настраиваем инструмент впервые. Для запуска Android-образов нам необходима физическая машина или VM с nested virtualisation — поддержкой. В практическом руководстве я демонстрирую, как это активировать на Linux VM. Однако если вы являетесь macOS пользователем и хотите развернуть Selenoid локально, то для запуска Android-тестов это будет невозможно. Но вы всегда можете запустить Linux VM локально с настроенной ‘nested virtualisation’ и развернуть Selenoid внутри.
Иллюстрация текущего состояния инфраструктуры
В контексте этой статьи мы добавим 2 инструмента для иллюстрации инфраструктуры. Это Selenium grid для web-тестов и Selenoid для Android-тестов. В руководстве на GitHub я также покажу, как использовать Selenoid для запуска web-тестов.
Ссылки для изучения
Аналогичные инструменты
- Существуют другие инструменты контейнеризации, но Docker – самый популярный. Если вы хотите попробовать что-то еще, то учтите, что те инструменты, которые мы рассмотрели для параллельного запуска Selenium-тестов, не будут работать из коробки.
- Как уже было сказано, существует много модификаций Selenium grid, например, Zalenium.
4. CI / CD
Краткое описание технологии
Практика непрерывной интеграции довольно популярна в разработке и стоит в одном ряду с системами контроля версий. Не смотря на это, я чувствую, что существует путаница в терминологии. В этом параграфе я бы хотел описать 3 модификации данной технологии с моей точки зрения. В интернете вы сможете найти много статей с различными интерпретациями, и это абсолютно нормально, если ваше мнение будет отличаться. Самое главное, чтобы вы были на одной волне с вашими коллегами.
Итак, существуют 3 термина: CI — Continuous Integration (непрерывная интеграция), CD — Continuous Delivery (непрерывная поставка) и снова CD — Continuous Deployment (непрерывное развертывание). (Далее я буду использовать эти термины на английском языке). Каждая модификация добавляет несколько дополнительных этапов к вашему конвейеру разработки. Но слово continuous (непрерывная) является самым главным. В этом контексте мы подразумеваем что-то, что происходит от начала и до конца, без прерываний или ручного воздействия. Давайте посмотрим на CI & CD и CD в данном контексте.
- Continuous Integration – это начальный шаг эволюции. После отправки нового кода на сервер, мы ожидаем получить быструю обратную связь, что с нашими изменениями все в порядке. Обычно CI включает запуск инструментов статического анализа кода и модульные/внутренние API тесты Это позволяет получать информацию о нашем коде уже несколько секунд/минут спустя.
- Continuous Delivery является более продвинутым шагом, на котором мы запускаем интеграционные/UI-тесты. Однако на данном этапе мы не получаем результаты так же быстро, как в случае с CI. Во-первых, эти типы тестов требует больше времени для прохождения. Во-вторых, перед запуском мы должны развернуть наши изменения на test/staging — среде. Более того, если мы говорим о мобильной разработке, то появляется дополнительный этап для создания сборки нашего приложения.
- Continuous Deployment предполагает, что мы автоматически выпускаем (release) наши изменения на production, если все приемочные тесты были пройдены на предыдущих этапах. В дополнение к этому после этапа release можно настроить различные этапы, такие как запуск smoke — тестов на production и сбор интересующих метрик. Continuous Deployment возможно только при хорошем покрытии автоматизированными тестами. Если требуются какие-то ручные вмешательства, в том числе и тестирование, то это больше не Continuous (непрерывное). Тогда мы можем говорить, что наш конвейер соответствует только практике Continuous Delivery.
Ценность для инфраструктуры автоматизации
В этом разделе я должен уточнить, что, когда мы говорим об end-to-end UI-тестах, это подразумевает, что мы должны разворачивать наши изменения и связанные сервисы на тестовых средах. Continuous Integration — процесс не применим для данной задачи и мы должны позаботиться о внедрении как минимум Continuous Deliver практик. Continuous Deployment также имеет смысл в контексте UI-тестов, если мы собираемся запускать их на production.
И перед тем как мы посмотрим на иллюстрацию изменения архитектуры, я хочу сказать несколько слов о GitLab CI. В отличие от других CI/CD-инструментов, GitLab предоставляет удаленный репозиторий и много других дополнительных функций. Таким образом, GitLab – это больше чем CI. Он включает из коробки управление исходным кодом, Agile управление, CI/CD pipelines, инструменты логирования и сборы метрик. Архитектура GitLab состоит из Gitlab CI/CD и GitLab Runner. Привожу краткое описание с официально сайта:
Gitlab CI/CD is a web application with an API that stores its state in a database, manages projects/builds and provides a user interface. GitLab Runner is an application which processes builds. It can be deployed separately and works with GitLab CI/CD through an API. For tests running you need both Gitlab instance and Runner.
Иллюстрация текущего состояния инфраструктуры
Ссылки для изучения
Аналогичные инструменты
5. Облачные платформы
Краткое описание технологии
В этом разделе мы поговорим о популярном тренде, который называется ‘публичные облака’. Несмотря на огромную пользу, которую дают описанные выше технологии виртуализации и контейнеризации, нам все еще необходимы вычислительные ресурсы. Компании приобретают дорогие сервера или арендуют дата-центры, но в таком случае необходимо сделать расчеты (иногда нереалистичные) того, как много ресурсов нам понадобится, будем ли мы их использовать 24/7 и для каких целей. Например, для production требуется работающий круглосуточно сервер, но нужны ли нам аналогичные ресурсы для тестирования в нерабочее время? Это также зависит от типа выполняемого тестирования. Примером могут быть нагрузочные/стрессовые тесты, которые мы планируем прогонять в нерабочие часы, чтобы получить результаты на следующий день. Но, определенно, круглосуточная доступность серверов не требуется для end-to-end авто-тестов и в особенности для сред ручного тестирования. Для таких ситуаций было бы хорошо получать столько ресурсов, сколько необходимо по требованию, использовать их и прекращать платить, когда они больше не нужны. Более того, было бы прекрасно получать их моментально, сделав несколько кликов мышкой или запустив пару скриптов. Для этого и используются публичные облака. Давайте посмотрим на определение:
«The public cloud is defined as computing services offered by third-party providers over the public Internet, making them available to anyone who wants to use or purchase them. They may be free or sold on-demand, allowing customers to pay only per usage for the CPU cycles, storage, or bandwidth they consume».
Бытует мнение, что публичные облака – это дорого. Но их ключевая идея – уменьшение расходов компании. Как было упомянуто ранее, публичные облака позволяют получить ресурсы по требованию и платить только за время их использования. Также, иногда мы забываем, что сотрудники получают зарплату, а специалисты тоже являются дорогим ресурсом. Необходимо учитывать, что публичные облака значительно облегчают поддержку инфраструктуры, что позволяет инженерам сфокусироваться на более важных задачах.
Ценность для инфраструктуры автоматизации
Какие конкретно ресурсы нам необходимы для end-to-end UI-тестов? В основном это виртуальные машины или кластеры (мы поговорим о Kubernetes в следующей секции) для запуска браузеров и эмуляторов. Чем больше браузеров и эмуляторов мы хотим запустить одновременно, тем больше CPU и памяти требуется и тем больше денег нам придется за это заплатить. Таким образом, публичные облака в контексте автоматизации тестирования позволяют нам запускать большое число (100, 200, 1000 …) браузеров/эмуляторов по требованию, получать результаты тестирования как можно быстрее и переставать платить за такие безумно ресурсозатратные мощности.
Самыми популярными облачными провайдерами являются Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform (GCP). В практическом руководстве представлены примеры использования GCP, но в целом неважно, что именно вы будете использовать для задач автоматизации. Все они предоставляют примерно одинаковый функционал. Обычно для выбора провайдера руководство фокусируется на всей инфраструктуре компании и бизнес-требованиях, что за рамками данной статьи. Для инженеров по автоматизации будет интереснее сравнить использование облачных провайдеров с использованием облачных платформ конкретно для целей тестирования, таких как Sauce Labs, BrowserStack, BitBar и так далее. Так давай те же сделаем это! На мой взгляд, Sauce Labs является самой известной фермой облачного тестирования, поэтому я и взял ее для сравнения.
GCP против Sauce Labs для целей автоматизации:
Представим, что нам нужно прогнать одновременно 8 web-тестов и 8 Android-тестов. Для этого мы будем использовать GCP и запустим 2 виртуальные машины с Selenoid. На первой мы поднимем 8 контейнеров с браузерами. На второй – 8 контейнеров с эмуляторами. Давайте взглянем на цены:
Для запуска одного контейнера с Chrome, нам понадобится n1-standard-1 машина. В случае с Android это будет n1-standard-4 для одного эмулятора. На самом деле более гибкий и дешевый способ – это задание конкретных пользовательских значений для CPU/Memory, но в данный момент для сравнения с Sauce Labs это не принципиально.
А вот тарифы на использование Sauce Labs:
Я полагаю, вы уже заметили разницу, но все же приведу таблицу с расчетами для нашей задачи:
Как видно, разница в стоимости огромна, особенно если запускать тесты только в рабочий двенадцатичасовой промежуток. Но можно еще сильнее сократить расходы, если использовать preemptible машины. Что же это такое?
A preemptible VM is an instance that you can create and run at a muchower price than normal instances. However, Compute Engine might terminate (preempt) these instances if it requires access to those resources for other tasks. Preemptible instances are excess Compute Engine capacity, so their availability varies with usage.If your apps are fault-tolerant and can withstand possible instance preemptions, then preemptible instances can reduce your Compute Engine costs significantly. For example, batch processing jobs can run on preemptible instances. If some of those instances terminate during processing, the job slows but does not completely stop. Preemptible instances complete your batch processing tasks without placing additional workload on your existing instances and without requiring you to pay full price for additional normal instances.
И это все еще не конец! В действительности я уверен, что никто не запускает тесты по 12 часов без перерыва. И если это так, то вы можете автоматически запускать и останавливать виртуальные машины, когда они не нужны. Реальное время использования может снизиться до 6 часов в сутки. Тогда оплата в контексте нашей задачи уменьшится аж до 11$ в месяц за 8 браузеров. Разве это не прекрасно? Но с preemptible машинами мы должны быть осторожны и готовы к прерываниям и нестабильной работе, хотя эти ситуации могут быть предусмотрены и обработаны программно. Оно того стоит!
Но ни в коем случае я не говорю ‘никогда не используйте облачные тестовые фермы’. Они имеют ряд преимуществ. Прежде всего это не просто виртуальная машина, а полноценное решение для автоматизации тестирования с набором функционала из коробки: удаленный доступ, логи, скриншоты, видеозапись, различные браузеры и физические мобильные устройства. Во многих ситуациях это может быть незаменимой шикарной альтернативой. Особенно тестовые платформы полезны для IOS-автоматизации, когда публичные облака могут предложить только Linux/Windows-системы. Но разговор про IOS будет в следующих статьях. Я рекомендую всегда смотреть по ситуации и отталкиваться от задач: в каких-то дешевле и эффективнее использовать публичные облака, а в каких то тестовые платформы определено стоят потраченных денег.
Иллюстрация текущего состояния инфраструктуры
Ссылки для изучения
Аналогичные инструменты:
6. Оркестрация
Краткое описание технологии
У меня хорошие новости – мы почти достигли конца статьи! На данный момент наша инфраструктура автоматизации состоит из web и Android-тестов, которые мы запускаем через GitLab CI параллельно, используя инструменты с поддержкой Docker: Selenium grid и Selenoid. Более того, мы используем созданные через GCP виртуальные машины для поднятия в них контейнеров с браузерами и эмуляторами. Для уменьшения расходов мы запускаем этим виртуальные машины только по требованию и останавливаем, когда тестирование не проводится. Существует ли что-то еще, что может улучшить нашу инфраструктуру? Ответ – да! Встречаем Kubernetes (K8s)!
Для начала рассмотрим, как слова оркестрация, кластер и Kubernetes связаны между собой. На высоком уровне оркестрация – это система, которая разворачивает и управляет приложениями. Для автоматизации тестирования такими контейнеризируемыми (containerised) приложениями являются Selenium grid и Selenoid. Docker и K8s дополняют друг друга. Первый используется для развертывания приложений, второй – для оркестрации. В свою очередь K8s является кластером. Задача кластера использовать VMs в качестве Nodes, что позволяет устанавливать различный функционал, программы и сервисы в рамках одного сервера (кластера). Если какой либо из Node упадет, то подхватятся другие Nodes, что обеспечивает нашему приложению бесперебойную работу. В дополнение к этому K8s имеет важную функциональность, связанную с масштабированием (scaling), благодаря чему мы автоматически получаем оптимальное количество ресурсов, основываясь на нагрузке и установленных ограничениях.
По правде говоря, ручное разворачивание Kubernetes с нуля является совсем нетривиальной задачей. Я оставлю ссылку на известное практическое руководство «Kubernetes The Hard Way», и, если вам интересно, вы можете попрактиковаться. Но, к счастью, существуют альтернативные способы и инструменты. Самым легкий из них – использовать Google Kubernetes Engine (GKE) в GCP, что позволит получить готовый кластер после нескольких кликов. Для начала изучения я рекомендую использовать именно этот подход, так как он позволит вам сфокусироваться на изучении того, как использовать K8s для своих задач вместо исследования того, как внутренние компоненты должны быть между собой интегрированы.
Ценность для инфраструктуры автоматизации
Рассмотрим несколько значимых функций, которые предоставляет K8s:
- развертывании приложения: использование multi-nodes кластера, вместо VMs;
- динамическое масштабирование: уменьшает расходы на ресурсы, которые используются только по требованию;
- самовосстановление (Self-healing): автоматическое восстановление pods (в результате чего восстанавливаются и контейнеры);
- выкатка обновления и откатов изменений без простоя: обновление инструментов, браузеров и эмуляторов не прерывает работу текущих пользователей
Но K8s – все еще не серебряная пуля. Для понимания всех преимуществ и ограничений в контексте рассматриваемых нами инструментов (Selenium grid, Selenoid) кратко обсудим строение K8s. Cluster содержит два типа Nodes: Master Nodes и Workers Nodes. Master Nodes отвечают за управление, развертывание и scheduling decisions. Workers nodes – это то, где приложения запущены. Nodes также содержат среду запуска контейнеров. В нашем случае это Docker, который отвечает за операции, связанные с контейнерами. Но есть и альтернативные решения, например containerd. Важно понимать, что масштабирование или самовосстановление не относится к контейнерам напрямую. Это реализуется через добавление/уменьшение числа pods, которые в свою очередь содержат контейнеры (обычно один container на pod, но в зависимости от задачи может быть и больше). Высокоуровневая иерархия представляет собой worker nodes, внутри которых находятся pods, внутри которых подняты контейнеры.
Функция масштабирования является ключевой и может быть применена как к nodes внутри cluster node-pool, так и к pods внутри node. Существует 2 типа масштабирования, которые относятся как к nodes, так и pods. Первый тип – горизонтальный – масштабирование происходит за счет увеличения числа nodes/pods. Такой тип является более предпочтительным. Второй тип, соответственно, вертикальный. Масштабирование осуществляется за счет увеличения размеров nodes/pods, а не их количества.
Теперь рассмотрим наши инструменты в контексте вышеупомянутых терминов.
Selenium grid
Как было упомянуто ранее, Selenium grid – очень популярный инструмент, и не сюрприз, что он был контейнеризирован (containerised). Следовательно, не вызывает удивление, что Selenium grid можно развернуть в K8s. Пример того, как это сделать, можно найти в официальном K8s-репозитории. Как обычно, прикладываю ссылки в конце секции. В дополнение к этому в практическом руководстве показано, как это сделать черед Terraform. Также есть инструкция, как масштабировать число pods, которые содержат контейнеры с браузерами. Но функция автоматического масштабирования в контексте K8s – все еще не до конца очевидная задача. Когда я начинал изучение, я не нашел никакого практического руководства или рекомендаций. После нескольких исследований и экспериментов при поддержке DevOps-команды мы выбрали подход поднятия контейнеров с нужными браузерами внутри одного pod, который находится внутри одного worker node. Такой способ позволяет нам применить стратегию горизонтального масштабирования nodes за счет увеличения их числа. Я надеюсь, что в будущем ситуация изменится, и мы увидим все больше и больше описаний лучших подходов и готовых решений, особенно после выпуска Selenium grid 4 с измененной внутренней архитектурой.
Selenoid:
В настоящее время развертывание Selenoid в K8s является самым большим разочарованием. Они не совместимы. Теоретически мы можем поднять Selenoid-контейнер внутри pod, но когда Selenoid начнет запускать контейнеры с браузерами, они все еще будут находиться внутри этого же pod. Это делает scaling невозможным и, как результат, работа Selenoid внутри кластера не будет отличаться от работы внутри виртуальной машины. Конец истории.
Moon:
Зная это узкое место при работе с Selenoid, разработчики выпустили более мощный инструмент, который назвали Moon. Этот инструмент был изначально задуман для работы с Kubernetes и, как результат, можно и нужно использовать функцию автомасштабирования. Более того, я бы сказал, что в настоящий момент это единственный инструмент в мире Selenium, который из коробки имеет native K8s cluster-поддержку (уже нет, см. следующий инструмент ). Ключевой особенностью Moon, которая обеспечивает данную поддержку, является:
Completely stateless. Selenoid stores in memory information about currently running browser sessions. If for some reason its process crashes — then all running sessions are lost. Moon contrarily has no internal state and can be replicated across data centers. Browser sessions remain alive even if one or more replicas go down.Итак, Moon шикарное решение, но с одной проблемой, он не бесплатный. Цена зависит от числа сессий. Бесплатно можно запустить только 0-4 сессии, что не особо полезно. Но, начиная уже с пятой сессии, придется заплатить по 5$ за каждую. Ситуация может отличаться от компании к компании, но в нашем случае использование Moon бессмысленно. Как я описывал выше, мы можем запустить VMs с Selenium Grid по требованию или увеличить число Nodes в кластере. Приблизительно на один pipeline мы запускаем 500 браузеров и останавливаем все ресурсы после завершения тестов. Если бы мы использовали Moon, нам бы пришлось заплатить дополнительных 500 x 5 = 2500 $ в месяц и не важно, как часто мы запускаем тесты. И опять же, я не говорю «не используйте Moon». Для ваших задач это может быть незаменимым решением, например, если у вас в организации много проектов/команд и вам нужен огромный общий кластер для всех. Как всегда, я оставляю ссылку в конце и рекомендую сделать все необходимые расчеты в контексте вашей задачи.
Callisto: (Внимание! Этого нет в оригинальной статье и содержится только в русском переводе)
Как я и сказал, Selenium – очень популярный инструмент, а сфера IT развивается очень быстро. Пока я работал над переводом, в сети появился новый многообещающий инструмент Callisto (привет Cypress и другим убийцам Selenium). Он работает нативно с K8s и позволяет запускать Selenoid-контейнеры в pods, распределено по Nodes. Все работает сразу из коробки, включая автомасштабирование. Фантастика, но надо тестировать. Мне уже удалось развернуть данный инструмент и поставить несколько экспериментов. Но выводы делать рано, после получения результатов на длинной дистанции, возможно, я сделаю обзор в следующих статьях. Пока оставляю только ссылки для самостоятельных исследований.
Иллюстрация текущего состояния инфраструктуры
Ссылки для изучения
Аналогичные инструменты
7. Инфраструктура как код (IaC)
Краткое описание технологии
И вот мы подобрались к последнему разделу. Обычно, данная технология и связанные с ней задачи не входят в зону ответсвенности инженеров по автоматизации. И на это есть свои причины. Во-первых, во многих организациях инфраструктурные вопросы находятся под контролем DevOps отдела и команды разработки не особо заботятся о том, благодаря чему работает pipeline и каким образом нужно поддерживать все, что с ним связано. Во-вторых, будем честными, практика «Инфраструктура как код (IaC)» все еще не применяется во многих компаниях. Но определенно это стало популярным трендом и важно стараться быть вовлеченным в связанные с этим процессы, подходы и инструменты. Или, по крайней мере, быть в курсе событий.
Начнем с мотивации использования данного подхода. Мы уже обсудили, что для запуска тестов в GitlabCI нам понадобятся как минимум ресурсы для запуска Gitlab Runner. А для запуска контейнеров с браузерами/эмуляторами нам нужно зарезервировать VM или кластер. Помимо ресурсов для тестирования, нам необходимо значительное число мощностей для поддержания сред разработки, staging, production, что также включает базы данных, автоматические расписания, конфигурации сети, балансировщик нагрузки, права пользователей и так далее. Ключевая проблема заключается в требуемых усилиях для поддержки этого всего. Есть несколько способов того, как мы можем вносить изменения и выкатывать обновления. Например, в контексте GCP мы можем использовать UI-консоль в браузере и выполнять все действия, кликая кнопки. Альтернативным способом может быть использование API-вызовов для взаимодействия с облачными сущностями или применение утилиты командной сроки gcloud для выполнения нужных манипуляций. Но при действительно большом количестве различных сущностей и инфраструктурных элементов становится тяжело или даже невозможно выполнять все операции вручную. Более того, все эти ручные действия неконтролируемые. Мы не можем отправить их на review перед выполнением, использовать систему контроля версий и быстро откатить правки, которые привели к инциденту. Для решения таких проблем инженеры создавали и создают автоматические bash/shell-скрипты, что ненамного лучше предыдущих способов, так как их не так уж и легко быстро прочесть, понять, поддерживать и модифицировать в процедурном стиле.
В этой статье и практическом руководстве я использую 2 инструмента, относящихся к практике IaC. Это Terraform и Ansible. Некоторые полагают, что не имеет смысла использовать их одновременно, так как их функционал схож и они взаимозаменяемые. Но дело в том, что изначально перед ними ставятся совершенно разные задачи. И факт того, что эти инструменты должны дополнять друг друга, был подтвержден на совместной презентации разработчиками, представляющими компании HashiCorp и RedHat. Концептуальная разница заключается в том, что Terraform – это provisioning-инструмент для управления самими серверами. В то время как Ansible является инструментом управления конфигурациями, задачей которого является установка, настройка и управление софтом на этих серверах.
Еще одной ключевой отличительной особенностью данных инструментов является стиль написания кода. В отличие от bash и Ansible, Terraform используют декларативный стиль, основанный на описании желаемого конечного состояния, которого необходимо достичь в результате выполнения. Например, если мы собираемся создать 10 VMs и применить изменения через Terraform, то мы получим 10 VMs. Если применить скрипт еще раз, ничего не произойдет, так как у нас уже есть 10 VMs, и Terraform знает об этом, поскольку он хранит текущее состояние инфраструктуры в state-файле. А вот Ansible использует процедурный подход и, если попросить его создать 10 VMs, то на первом запуске мы получим 10 VMs, аналогично с Terraform. Но после повторного запуска у нас уже будет 20 VMs. В этом и заключается важное отличие. В процедурном стиле мы не храним текущее состояние и просто описываем последовательность шагов, которые должны быть выполнены. Разумеется, мы можем обработать различные ситуации, добавить несколько проверок на существование ресурсов и текущее состояние, но нет смысла тратить наше время и прикладывать усилия на контролирование данной логики. К тому же это увеличивает риск совершить ошибки.
Обобщив все выше сказанное, можно сделать вывод, что для provisioning серверов более подходящим инструментом является Terraform и декларативная нотация. А вот работу по управлению конфигурациями лучше делегировать на Ansible. Разобравшись с этим, давайте посмотрим на примеры использования в контексте автоматизации.
Ценность для инфраструктуры автоматизации
Здесь важно понимать лишь то, что инфраструктура автоматизации тестирования должна рассматриваться как часть всей инфраструктуры компании. А это значит, что все IaC-практики должны быть применены глобально к ресурсам всей организации. Кто за это ответственен, зависит от ваших процессов. DevOps-команда более опытна в данных вопросах, они видят всю картину происходящего. Однако QA-инженеры сильнее вовлечены в процесс построения автоматизации и структуру pipeline, что позволяет им лучше видеть все требуемые изменения и возможности для улучшения. Самый лучший вариант – это работать сообща, обмениваться знаниями и идеями для достижения ожидаемого результата.
Приведу несколько примеров использования Terraform и Ansible в контексте автоматизации тестирования и инструментов, которые мы обсуждали до этого:
1. Описать через Terraform необходимые характеристики и параметры VMs и кластеров.
2. Установить с помощью Ansible необходимые для тестирования инструменты: docker, Selenoid, Selenium Grid и загрузить нужные версии браузеров/эмуляторов.
3. Описать через Terraform характеристики VM, в которой будет запущен GitLab Runner.
4. Установить с помощью Ansible GitLab Runner и необходимые сопутствующие инструменты, задать настройки и конфигурации.
Иллюстрация текущего состояния инфраструктуры
Ссылки для изучения:
Аналогичные инструменты
Подведем итоги!
Mind map диаграммы: эволюция инфраструктуры
step1: Local
step2: VCS
step3: Containerisation
step4: CI/CD
step5: Cloud Platforms
step6: Orchestration
step7: IaC
Что дальше?
Итак, это конец статьи. Но в заключении я бы хотел установить с вами некоторые договоренности.
С вашей стороны
Как было сказано вначале, я бы хотел, чтобы статья несла практическую пользу и помогла вам применить полученные знания в реальной работе. Добавляю еще раз ссылку на практическое руководство.
Но даже после этого не останавливайтесь, практикуйтесь, изучайте соответствующие ссылки и книжки, узнавайте, как это работает у вас в компании, находите места, которые можно улучшить и принимайте в этом участие. Удачи!
С моей стороны
Из заголовка видно, что это была только первая часть. Несмотря на то, что она получилось довольно большой, здесь все еще не раскрыты важные темы. Во второй части я планирую рассмотреть инфраструктуру автоматизации в контексте IOS. Из-за ограничений Apple, связанных с запусками IOS симуляторов только на macOS системах, наш набор решений сужен. Например, мы лишены возможности использовать Docker для запуска симулятора или публичных облаков для запуска виртуальных машин. Но это не означает, что нет других альтернатив. Я постараюсь держать вас в курсе передовых решений и современных инструментов!
Также я не упомянул довольно большие темы, связанные с мониторингом. В части 3 я собираюсь рассмотреть наиболее популярные инструменты для мониторинга инфраструктуры, а также какие данные и метрики стоит принять во внимание.
И напоследок. В будущем я планирую выпустить видео курс по построению тестовой инфраструктуры и популярным инструментам. В настоящее время в интернете довольно много курсов и лекций по DevOps, но все материалы представлены в контексте разработки, но не автоматизации тестирования. В этом вопросе мне очень нужна обратная связь, будет ли такой курс интересен и ценен для сообщества тестировщиков и автоматизаторов. Заранее спасибо!
Комментариев нет:
Отправить комментарий