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

Моя дилемма

Я работаю с Selenium Webdriver/WebdriverIO уже много лет, и самая большая претензия, которую я имею, заключается в том, что мне нужно запустить сервер Selenium, прежде чем начинать тесты.

Это может показаться незначительной проблемой, но это означает, что в моем терминале открыта еще одна вкладка, запуск/остановка этого процесса, и все это становится намного сложнее, когда вы пытаетесь автоматизировать его в среде CI. В дополнение к этому вам необходимо установить Java для запуска сервера Selenium (или вы можете использовать пакет npm selenium-standalone, который удаляет зависимость от Java, но его все равно нужно запускать/останавливать).

Хотя такие решения, как Browserstack и Saucelabs, довольно популярны, они не являются самым быстрым способом получения отзыва, и иногда вам просто нужно быстро запустить Chrome, чтобы убедиться, что все в порядке.

Так как же решить проблему с необходимостью постоянно запускать и останавливать сервер Selenium? Другими словами, как вы создаете контейнер, который работает изолированно и заботится о запуске/остановке сервера селена за вас? (плюс запуск ваших тестов, конечно).

Войдите в мир Docker (и Docker Compose)

Я пристрастился к Докеру: сейчас бы все контейнеризировал.
Это настолько простой способ решения (или, даже лучше, отказа от решения) совместимости ОС, что это не проблема.

Давайте применим его к простому тестовому случаю: запуск примера webdriverIO.

Конечно, у нашего приложения также будет свой собственный package.json со всеми перечисленными там зависимостями и wdio.conf со всей конфигурацией WebdriverIO, но эй, мы все это знаем!

tests/  
|-index.spec.js
Dockerfile  
docker-compose.yml  
wdio.conf  
package.json

Наш package.json определяет такой тестовый скрипт: "test: wdio wdio.conf".

Для запуска тестов нам нужно установить зависимости npm и запустить команду npm:

$ npm i 
$ npm test

Создание приложения

Не нужно устанавливать node.js, не нужно устанавливать npm. Просто Docker и Dockerfile, например:

Это просто определение того, что мы хотим, рецепт. Чтобы собрать из него образ, нам понадобится немного Docker-магии (docker build):

docker build -t webdriverapp .

На простом английском языке: «Создайте файл Dockerfile в этой папке и назовите результат «webdriverapp»». Результатом сборки является изображение.

Для запуска образа и создания контейнера нам понадобится еще немного Docker-магии (docker run):

docker run --rm -ti webdriverapp npm test

Проще говоря: «Выполните команду npm test из образа с именем 'webdriverapp' в интерактивном режиме (-ti) и затем удалите контейнер (--rm).

Были хороши! Запустите его, и вы получите сообщение об ошибке, говорящее о том, что нам нужен работающий сервер Selenium!

docker-compose

Нам определенно нужно больше, чем просто контейнерная версия нашего приложения: нам нужен целый стек (в данном случае это сервер Selenium, но это может быть сервер Redis, сервер mongodb и т. д.) приложений, которые работают изолированно. и могут общаться друг с другом.

Docker Hub похож на npm для Docker, там вы можете найти всевозможные готовые образы. Оказывается, ребята из Selenium опубликовали докеризированную версию автономного Selenium, selenium/standalone-chrome. Запуск его с докером создаст контейнер с сервером селена, прослушивающим порт по умолчанию 4444 (всегда помните, что когда вы запускаете контейнер, который прослушивает порт, вы должны сопоставить этот порт на своем хосте).

$ docker run -p 4444:4444 selenium/standalone-chrome

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

docker-compose — вот ответ. Это позволяет нам создать файл (docker-compose.yml), в котором мы определяем наш стек и то, как различные приложения взаимодействуют друг с другом.
Легче сделать, чем сказать:

Файл определяет два приложения: app и selenium:

  • app необходимо собрать, а файл Dockerfile находится в том же каталоге, что и docker-compose.yml (build: .). При запуске мы хотим запустить определенную команду: command: npm test -- --host selenium
    Мы также хотим, чтобы она имела ссылку на приложение selenium.
  • Вместо этого selenium не нужно собирать, он использует готовый образ из Docker Hub: image: selenium/standalone-chrome. Он также предоставляет доступ к порту 4444.

Обратите внимание, что docker-compose создает хост для каждого приложения, предоставляющего порт, а имя хоста — это имя приложения: в данном случае selenium. Вот почему мы передаем параметр --host selenium в WebdriverIO: чтобы сообщить ему где сервер слушает.

Время создания стека: docker-compose build.
И запустите его: docker-compose up.

Сделанный!

репозиторий GitHub

Полностью рабочий пример кода можно найти на GitHub.

Выводы

Docker и docker-compose могут помочь нам по-разному: мы можем составлять целые стеки за считанные минуты. Нужна база данных Redis? Добавьте его в docker-compose. Нужна очередь RabbitMq? Добавьте это! Это простой и эффективный способ упаковки приложения и его зависимостей.

Конечно, в производственной среде ваши сервисы будут где-то размещены: нет проблем! У вас могут быть разные файлы docker-compose для разных сред, каждый из которых определяет разные стеки!

Первоначально опубликовано на blog.ricca509.me 5 сентября 2016 г.