Javascript Testing with Selenium Webdriver and Mocha
Если вы хотите написать функциональный тест на Javascript, следующий туториал предоставляет идеальный структурный и справочный материал для инженера по автоматизации пользовательского интерфейса для тестирования Javascript с помощью Selenium Webdriver 3, Mocha и NodeJS.
В наши дни Javascript - это повсеместный веб-язык, который, кажется, преодолел «пресловутое» прошлое и стал более надежной платформой не только для клиентских, но и для серверных доменов. Mochajs, или просто Mocha, представляет собой многофункциональную тестовую среду JavaScript, работающую на Nodejs, которая предоставляет платформу и API для создания автономных приложений на стороне сервера с использованием движка Google V8 Javascript в его основе.
* Примечание. Чтобы начать работу с этим руководством по Javascript, вам необходимо знать основы языка программирования NodeJS и Javascript.

Agenda:
Создание тестов с помощью Mocha
- Введение в Mocha
- Установка Mocha
- Установка модуля Chai Assertion
- Набор тестов и структура тестового набора
- Запуск набора тестов и тестовых примеров Mocha
- Управление синхронизацией кода асинхронного тестирования
Интеграция MochaJS с Selenium Webdriver 3
Builder with Options
Builder with Capabilities
Selenium Webdriver Control Flow и управление обещаниями
MochaJS + Selenium Webdriver
- Поддержка Selenium Webdriver для MochaJSВведение в Selenium
- Установка Selenium
- Webdriver Construction
- Builder with Options
- Builder with Capabilities
- Selenium Webdriver Control Flow
- MochaJS + Selenium Webdriver
- Поддержка Selenium Webdriver для MochaJS
Используемые версии:
- Используемая версия узла: 6.10.1 (LTS)
- Мокко: 2.5.3
- WebdriverJS: 3.3.0
1. Создание тестов с помощью Mocha
Введение в Mocha
Mocha - это многофункциональная среда тестирования JavaScript, работающая на Node.js и в браузере, что делает асинхронное тестирование простым и увлекательным . Тесты Mocha запускаются последовательно, что позволяет создавать гибкие и точные отчеты, сопоставляя неперехваченные исключения с правильными тестовыми примерами.
MochaJS — это JavaScript фреймворк, используемый для автоматического тестирования приложений. Он может использоваться как на стороне сервера Javascript, так и в браузере. ChaiJS — это библиотека для node и, как Mocha, Chai может использоваться на стороне сервера или в браузере. Chai может быть использован совместно с любой библиотекой для тестирования.
Mocha предоставляет API, который определяет способ структурирования кода тестирования в наборы тестов и модули тестовых примеров для выполнения, а затем для создания отчета о тестировании. Mocha предоставляет два режима работы: либо из командной строки (CLI), либо программно (Mocha API).
Установка Mocha
Если mocha должен использоваться в CLI, он должен быть установлен глобально, как и Nodejs.
npm install -g mocha
Установка Chai Assertion модуля
npm install --save chai
Параметр «–save» используется для того, чтобы модуль был установлен в рамках проекта, а не глобально.
Набор тестов и структура тестовых примеров
В Mocha набор тестов определяется ключевым словом description, которое принимает функцию обратного вызова. Набор тестов может содержать дочерние/внутренние наборы тестов, которые могут в свою очередь содержать свои собственные дочерние наборы тестов и т.д. Тестовый пример обозначается функцией «it», которая принимает функцию обратного вызова и содержит код тестирования соответственно.
Mocha поддерживает настройку набора тестов и функции настройки тестового набора. Настройка набора тестов обозначается «before», а настройка тестового набора - «beforeEach». «beforeEach» на самом деле является общей настройкой для каждого тестового случая в пакете и будет выполняться перед каждым тестом.
Как и в случае с настройкой, Mocha поддерживает функции набора тестов и разборки тестовых примеров. Разборка набора тестов обозначается как «After», а разборка тестового набора реализуется функцией «afterEach», которая выполняется после набора тестов и после каждого тестового примера, соответственно.
Создайте файл, который будет содержать набор тестов, например test_suite.js, и напишите в него следующее:
describe("Inner Suite 1", function(){
before(function(){
// do something before test suite execution
// no matter if there are failed cases
});
after(function(){
// do something after test suite execution is finished
// no matter if there are failed cases
});
beforeEach(function(){
// do something before test case execution
// no matter if there are failed cases
});
afterEach(function(){
// do something after test case execution is finished
// no matter if there are failed cases
});
it("Test-1", function(){
// test Code
// assertions
});
it("Test-2", function(){
// test Code
// assertions
});
it("Test-3", function(){
// test Code
// assertions
});
});
Запуск Mocha Тестовых сценариев
Mocha поддерживает выполнение тестов тремя способами: файл целого набора тестов, тесты, отфильтрованные по шаблонам «grep», и тесты с фильтрацией grep, просматривающие дерево каталогов (рекурсивный вариант)
- Запустить весь файл Test Suite.
mocha /path/to/test_suite.js
- Запустить определенный набор или тест из определенного файла набора.
Если выбран набор, то будут выполнены все дочерние наборы и / или тесты.
mocha -g “Test-2” /path/to/test_suite.js
- Запустить конкретный набор или тестовый файл, рекурсивно выполняя поиск в дереве каталогов.
mocha --recursive -g “Test-2” /directory/
Для расширенных возможностей интерфейса командной строки:
mocha –-help
Управление синхронизацией кода асинхронного тестирования
В случае, если асинхронные функции используются с Mocha и не обрабатываются должным образом, вы можете столкнуться с трудностями. Если асинхронный код (например, http-запросы, файлы, селен и т.д.) Должен использоваться в тестовом примере, следуйте этим рекомендациям, чтобы избежать неожиданных результатов:
a) ‘done’ Функция
В вашей тестовой функции («it») вам нужно передать функцию 'done' по цепочке обратных вызовов, это гарантирует, что она будет выполнена после вашего последнего шага:
В приведенном ниже примере подчеркивается выполненная функциональность, в этом случае в конце тестовой функции произойдет тайм-аут 3 секунды.
it(‘Test-1’, function(done){
setTimeout(function(){
console.log(“timeout!”);
// mocha will wait for done to be called before exiting function.
done();
}, 3000);
});
b) Возврат промиса
Возврат промиса - еще один способ убедиться, что Mocha выполнил все строки кода при использовании асинхронных функций (функция «готово» в этом случае не требуется).
it(‘Test-1’, function(done){
var promise;
promise = new Promise(function(resolve, reject){
setTimeout(function(){
console.log("Timeout");
resolve();
}, 3000);
});
// mocha will wait for the promise to be resolved before exiting
return promise;
});
2. Интеграция Javascript Selenium 3 с MochaJS:
Введение в Selenium
Selenium - это библиотека, которая управляет веб-браузером и имитирует поведение пользователя. В частности, Selenium предлагает пользователю API-интерфейсы конкретных языковых библиотек, которые называются «привязками». Эти «привязки» действуют как клиент для выполнения запросов к промежуточным компонентам и действуют как серверы, чтобы окончательно управлять браузером.
API-интерфейсы Selenium или привязки теперь существуют во всех популярных языках разработки. Все языковые реализации согласились соблюдать согласованность с соглашениями об именах функций API.
Промежуточными компонентами может быть фактический веб-драйвер, изначально присутствующий в каждом пакете Selenium: selenium-standalone-server, а также драйверы, управляющие собственным браузером поставщика, такие как Geckodriver для Mozilla, chromedriver для Chrome и т. д. Более того, веб-драйвер Selenium взаимодействует с браузером. Драйверы через протокол JsonWired и становятся веб-стандартом W3C.
Установка Selenium
Прежде чем углубиться в интеграцию Selenium с MochaJS, мы кратко рассмотрим реализацию Selenium с помощью Node JS.
Чтобы использовать Selenium API для Javascript (или привязок Selenium Javascript), мы должны установить соответствующий модуль:
npm install selenium-webdriver
Здесь следует уточнить, что Javascript Selenium Webdriver может в равной степени именоваться (хотя и не в npm) как «Webdriverjs». Хотя Webdrivejs отличается от других библиотек / модулей, таких как WebdriverIO , Protractor и т.д.: selenium-webdriver - это официальная библиотека Selenium для Javascript с открытым исходным кодом, а остальные - это библиотеки-оболочки / фреймворки , созданные поверх webdriverjs. API , претендующий на повышение удобства использования и обслуживания.
В коде NodeJS используется:
require(‘selenium-webdriver’)
Webdriver Construction
Чтобы иметь возможность использовать Selenium, мы должны создать соответствующий объект «webdriver», который затем будет управлять нашим браузером. Ниже мы можем увидеть, как мы используем шаблон «Строитель» для создания объекта webdriver путем объединения нескольких функций:
Builder with Options
var webdriver = require('selenium-webdriver')
var chrome = require('selenium-webdriver/chrome'),
var firefox = require('selenium-webdriver/firefox');
var driver = new webdriver.Builder()
.forBrowser(‘firefox’)
.setFirefoxOptions( /* … */)
.setChromeOptions( /* … */)
.build();
В приведенном выше коде нам удалось создать объект webdriver, который объединяет конфигурацию для более чем одного браузера (обратите внимание на методы 'options'), несмотря на то, что метод 'forBrowser ()' явно устанавливает 'firefox'.
Пользователь может установить переменную среды SELENIUM_BROWSER во время выполнения, чтобы установить желаемый браузер, она переопределит любую опцию, установленную с помощью 'forBrowser', поскольку мы уже настроили несколько возможностей браузера с помощью 'set <browser_name> Option s'.
Свойства браузера могут содержать несколько типов информации в зависимости от тестируемого браузера. Например, в свойствах Mozilla мы можем установить желаемую конфигурацию «профиля» следующим образом:
var profile = new firefox.Profile( /* … path to firefox local profile … */); var firefoxOptions = new firefox Options().setProfile(profile);
Затем в приведенном выше фрагменте Builder мы можем добавить: 'setFirefoxOptions (firefoxOptions)'
Builder with Capabilities
Selenium Webdriver Javascript API документирует несколько способов создания веб-драйвера. Еще один возможный способ - установить всю необходимую конфигурацию драйвера в возможностях:
var driver = new webdriver.Builder().
.withCapabilities( { ‘browserName’ : ‘firefox’ } )
.build();
Обратите внимание, что если setOptions установлен после 'withCapabilities', конфигурации будут переопределены (например, конфигурации прокси).
Selenium Webdriver Control Flow и управление промисами
Поскольку Javascript и NodeJS основаны на асинхронных принципах, Selenium Webdriver ведет себя аналогичным образом. Чтобы избежать пирамид обратных вызовов и помочь инженеру по тестированию с опытом написания сценариев, а также с удобочитаемостью кода и удобством обслуживания, объект Selenium Webdriver включает диспетчер обещаний, который использует ControlFlow. ControlFlow - это класс, отвечающий за последовательное выполнение асинхронных команд веб-драйвера.
Практически каждая команда выполняется для объекта «драйвер», и возвращается обещание. Следующие команды не должны быть вложены в 'thens', если нет необходимости обрабатывать значение, разрешенное обещанием, следующим образом:
driver.get("http://www.google.com");
driver.getTitle().then(function( title ) {
// google page title should be printed
console.log(title)
});
driver.quit();
Указатели для тестирования Javascript с помощью Selenium Webdriver и Mocha:
- 'driver' - это объект webdriver, а не объект промисов
- 'driver.getTitle ()' или driver.get (url) или любая другая команда selenium d возвращает объект промиса.
Это означает, что мы можем выполнить следующее:
var titlePromise = driver.getTitle();
titlePromise.then(function(title){
console.log(title);
});
3. Кроме того, поскольку «драйвер» является асинхронным в своей основе, следующее не будет работать:
var title = driver.getTitle();
expect (title).equals("Google");
Примечание. «Title» - это объект промиса, а не фактическое разрешенное значение.
MochaJS + Selenium Webdriver
Вообще говоря, selenium webdriver может быть интегрирован с MochaJS, поскольку он используется в любом простом скрипте NodeJS. Однако, поскольку Mocha не знает, когда асинхронная функция завершилась до того, как будет вызвана 'done ()' или будет возвращено обещание, мы должны быть очень осторожны с обработкой.
На основе промисов
Команда Selenium регистрируется автоматически, чтобы гарантировать, что команды webdriver выполняются в последовательном и правильном порядке, обещание должно быть возвращено.
Приведенные ниже коды показывают Mocha (before, beforeEach, after, afterEach) или тело тестового примера, которое он перехватывает.
describe( 'Test Suite' , function(){
before(function(){
driver.get( my_service );
driver.findElement(webdriver.By.id(username)).sendKeys(my_username);
// a promise is returned while ‘click’ action
// is registered in ‘driver’ object
return driver.findElement(webdriver.By.id(submit)).click();
});
after(function(){
return driver.quit();
});
it( 'Test Case', function(){
driver.getTitle().then(function(title){
expect(title).equals(my_title);
})
Будут выполнены следующие действия:
- Страница браузера «my_service» загружена
- Текстовое поле с идентификатором "имя пользователя" находится
- Текстовое поле с идентификатором username заполняется my_username
- Заголовок страницы извлекается и проверяется на соответствие "my_title"
- Webdriver закрывается, окно браузера закрывается, и процесс браузера завершается.
Поддержка Selenium Webdriver для MochaJS
Чтобы выполнить тестирование Javascript с помощью Selenium Webdriver и Mocha простым способом, webdriver упрощает использование MochaJS, оборачивая тестовые функции MochaJS (before, beforeEach, it и т. Д.) С помощью объекта test, создавая область, которая обеспечивает понимание того, что webdriver уже используется. Следовательно, в возврате Promise нет необходимости.
Сначала необходимо загрузить соответствующий модуль:
<span style="font-weight: 400;">var test = require('selenium-webdriver/testing');</span>
Всем функциям Mocha предшествует «test».
следующим образом:
test.before() test.describe(), etc
Затем приведенный выше код полностью переписывается как:
test.describe( 'Test Suite' , function(){
test.before(function(){
driver.get( my_service );
driver.findElement(webdriver.By.id(username)).sendKeys(my_username);
driver.findElement(webdriver.By.id(submit)).click();
});
test.after(function(){
driver.quit();
});
test.it( 'Test Case' , function(){
driver.getTitle().then(function(title){
expect(title).equals(my_title);
})
driver.sleep();
});
});
Заключение
В этом туториале мы получили возможность испытать тестирование Javascript с помощью Selenium Webdriver и MochaJS. При сравнении привязок к другим языкам программирования следует иметь в виду основное отличие из-за асинхронной природы NodeJS, MochaJS и Selenium Webdriver.
Пока мы продолжаем возвращать обещания в любой функции, которая создает обещание (либо в пользовательской тестовой функции библиотеки, либо в хуке / тестовом примере MochaJS), Mocha будет выполнять их в правильном порядке.
Другие фреймворки, такие как WebdriverIO, Protractor и CodeseptJS, предоставляют решения-оболочки, которые скрывают некоторые конфигурации от пользователя и обеспечивают улучшенную обработку Promise для улучшения работы со сценариями, а так же могут оказаться полезными для многих экспертов по автоматизации тестирования.