Для запуска функциональных тестов нам понадобятся:
- Node.js — надеюсь, он у вас уже установлен;
- Python 2.7.х — указан в зависимостях модуля
selenium-webdriver
и должен быть установлен в систему до загрузки остальных пакетов; - Java Runtime Environment — среда для запуска Selenium Server;
- mocha — с помощью этой утилиты мы будем запускать тесты; устанавливается командой
npm i -g mocha
; -
selenium-webdriver — через него мы будем оправлять Selenium-серверу команды и получать от него данные со страницы; устанавливается в папку проекта командой
npm i selenium-webdriver
; - Selenium server
— запускает и закрывает браузер, отправляет браузеру команды и т.п.; не требует особой установки; скачиваем JAR-файл в папку рядом с тестами;
- Driver Provider
— вспомогательный класс, в котором сосредоточен код для запуска и остановки сервера и конфигурация драйвера (например, выбор браузера для тестирования).
Когда всё перечисленное будет установлено, можно начинать писать и запускать тесты.
В каждом пакете тестов нужно создать экземпляр класса DriverProvider
. Как я указал выше, с его помощью мы будем управлять сервером и драйвером.
var driverProvider = new DriverProvider();
Перед запуском пакета тестов выполняется метод before
:
test.before(function () {
return driverProvider.startUp();
});
По окончании работы тестов выполняется метод after
:
test.after(function () {
return driverProvider.tearDown();
});
DriverProvider
— это хорошая точка расширения функциональности. В этом классе можно управлять конфигурацией драйвера без вмешательства в код самих тестов. Например, я указываю там браузер, в котором нужно запустить тест. Код можно слегка поправить для использования удалённого Selenium-сервера или запуск специального прокси-сервера.
В методах startUp()
и tearDown()
этого класса выполняются задачи по запуску и остановке соответствующих сервисов. Они должны возвращать promise-объект. По его состоянию будет определяться завершена-ли задача или нет.
Отличительной особенностью API selenium-webdriver
является то, что большинство методов выполняются асинхронно. Однако, постоянно использоваться promise-объекты, чтобы обеспечить нужный порядок выполнения команд, вовсе не требуется. Для этого есть так называемые “control flow”. Внутри одного потока все команды будут исполняться синхронно по мере того как они были добавлены в поток. Это немного облегчает написание тестов. Но, если нужно получить значение из функции (например, список элементов, размеры элемента и т.д.), то без “обещаний” не обойтись.
Так же библиотека selenium-webdriver/testing
тоже использует “control flow” чтобы последовательно исполнять содержимое тестов. Она дублирует методы mocha. Тест может вернуть promise-объект и он будет считаться завершённым, когда обещание будет установлено в какое-либо состояние. Если тест ничего не вернул, то он будет считаться завершенным, когда очередь заданий окажется пуста.
И в заключение команда, которая запустит на выполнение наш тест:
mocha page-spec.js
У команды mocha есть масса полезных параметров. Мне, например, нравятся отчёты в виде спецификации. Ещё можно указать
максимальное время выполнения теста. Функциональные тесты, как правило, не быстрые и 2 секунды на тест (значение по-умолчанию) совсем не хватает, чтобы его выполнить.
В заключение, хочу обратить внимание на шаблон написания тестов Page Object
. Этот подход позволяет выделить взаимодействие с WebDriver и повторяющиеся во время тестирования действия в изолированные классы. Практика показывает, что таким образом легче поддерживать тесты в актуальном состоянии.