Поскольку функциональные тесты являются неотъемлемой частью рабочего процесса веб-приложений, мы всегда должны пытаться найти способы сделать их более плавными и облегчить нашу жизнь.
Моя дилемма
Я работаю с 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 г.