Статьи

Функциональное тестирование JavaScript с Nightwatch.js

Некоторое время назад Эрик Эллиотт написал « Тестирование JavaScript: тесты« единица против функциональности »и« интеграционные тесты »» , в котором он объяснил различные типы тестов и когда их использовать.

В сегодняшней статье я хотел бы углубиться в функциональное тестирование JavaScript. Для этого мы исследуем и используем библиотеку Nightwatch.js .

Но прежде чем начать, позвольте мне напомнить вам, что такое функциональный тест и почему он важен. Грубо говоря, функциональное тестирование — это процесс, направленный на то, чтобы приложение работало так, как ожидается с точки зрения пользователя.

Мы не говорим о технических тестах, таких как модульные или интеграционные тесты. Здесь цель состоит в том, чтобы убедиться, что пользователь может беспрепятственно выполнить определенный сценарий, например войти в платформу, купить продукт и т. Д.

Представляем Nightwatch.js

Nightwatch.js представляет собой комплексную среду тестирования, основанную на Node.js. Он опирается на Selenium , проект, направленный на содействие автоматизации веб-браузера.

Благодаря удобному для человека синтаксису, Nightwatch.js позволяет «сценарировать» сценарии, которые затем автоматически воспроизводятся браузером (не обязательно без заголовка).

Установка Nightwatch

Nightwatch сам по себе является модулем Node.js, что означает, что вам понадобится Node, установленный на вашем компьютере. Самый простой способ сделать это — использовать менеджер версий, такой как nvm . Nightwatch распространяется по npm, поэтому вы можете установить его как любой другой модуль — либо глобально с -g , либо внутри текущего проекта с помощью --save-dev .

 npm install --save-dev nightwatch 

Nightwatch использует API Selenium WebDriver и, следовательно, нуждается в сервере Selenium WebDriver. Это работает на Java, что означает, что вам также необходимо установить Java Development Kit (JDK 7+) в вашей среде. Вы можете скачать JDK с сайта Oracle.

После загрузки и установки вы можете убедиться, что Java правильно доступна на вашем компьютере с помощью java -version . Последний шаг — загрузка отдельного сервера Selenium, упакованного в виде jar- файла, со страницы загрузок Selenium . Я рекомендую поместить его в папку bin внутри вашего проекта.

 your_project/ | |– bin/ | |– selenium-server-standlone-2.53.1.jar | `– package.json 

Хорошо, мы все готовы. Давайте начнем.

Настройка Nightwatch

Как вы можете себе представить, у Nightwatch много настроек. К счастью, нам не нужно знать все, чтобы начать. Конфигурация может nightwatch.json файле nightwatch.json или в файле nightwatch.conf.js в корне вашего проекта. Я бы порекомендовал позже, поскольку это немного более гибко, а также дает вам возможность добавлять комментарии.

 var SELENIUM_CONFIGURATION = { start_process: true, server_path: 'bin/selenium-server-standalone-2.53.0.jar', host: '127.0.0.1', port: 4444 }; var FIREFOX_CONFIGURATION = { browserName: 'firefox', javascriptEnabled: true, acceptSslCerts: true }; var DEFAULT_CONFIGURATION = { launch_url: 'http://localhost', selenium_port: 4444, selenium_host: 'localhost', desiredCapabilities: FIREFOX_CONFIGURATION }; var ENVIRONMENTS = { default: DEFAULT_CONFIGURATION }; module.exports = { src_folders: ['tests'], selenium: SELENIUM_CONFIGURATION, test_settings: ENVIRONMENTS }; 

Примечание. Мне лично легче читать файл конфигурации, когда он разбит на более мелкие объекты конфигурации, что не разрешено в файле JSON.

В нашем случае мы сообщаем Nightwatch, что наши тесты будут находиться в папке для tests , используя определенную конфигурацию Selenium и определенные настройки теста. Давайте рассмотрим каждый кусок:

 var SELENIUM_CONFIGURATION = { start_process: true, server_path: 'bin/selenium-server-standalone-2.53.0.jar', host: '127.0.0.1', port: 4444 }; 

С помощью этого объекта конфигурации мы говорим Selenium работать на 127.0.0.1:4444 , что является значением по умолчанию для Nightwatch. Мы также следим за тем, чтобы он автоматически загружался с сервера Selenium, который мы скачали и сохранили в нашей папке bin .

Примечание: для более продвинутого использования обязательно проверьте список всех опций Selenium .

Переходя к фактической настройке тестирования:

 var DEFAULT_CONFIGURATION = { launch_url: 'http://localhost', selenium_port: 4444, selenium_host: 'localhost', desiredCapabilities: FIREFOX_CONFIGURATION }; var ENVIRONMENTS = { default: DEFAULT_CONFIGURATION }; 

Опция test_settings из Nightwatch ожидает объект, ключи которого являются именами каждой среды, сопоставленные с дополнительным объектом конфигурации. В нашем случае мы еще не настроили пользовательскую среду, поэтому используем default . Позже у нас может быть среда staging или production тестирования.

В конфигурации среды мы сообщаем Nightwatch, какой URL открывать (который будет отличаться, например, для постановки), и какой браузер следует использовать для запуска тестов.

Примечание: для более продвинутого использования обязательно проверьте список всех вариантов тестирования .

 var FIREFOX_CONFIGURATION = { browserName: 'firefox', javascriptEnabled: true, acceptSslCerts: true }; 

В нашем сценарии мы будем использовать Firefox без поддержки JavaScript, что позволяет использовать SSL-сертификаты. Мы могли бы пойти дальше и указать конкретную версию браузера (с version ) или ОС (с platform ).

Узел: для более продвинутого использования, обязательно проверьте список всех возможностей возможностей .

Хорошо, теперь у нас есть правильная конфигурация. Время написать первый тест!

Написание теста Nightwatch

Для нашего теста мы рассмотрим страницу входа в /login , содержащую поле электронной почты, поле пароля и кнопку отправки. При отправке формы пользователь должен перенаправить на страницу с надписью «Лента новостей».

В нашей конфигурации мы указали, что тесты находятся в папке с именем tests . Давайте создадим эту папку с tests , а также файл с именем login.js .

 your_project/ | |– bin/ | |– selenium-server-standlone-2.53.1.jar | |– tests/ | |– login.js | |- nightwatch.conf.js `– package.json 

Этот файл экспортирует объект, который описывает наш сценарий. Каждый ключ (если их несколько) — это имя теста, сопоставленное с функцией, содержащей шаги для выполнения.

 module.exports = { 'Login test': function (client) { // Steps to execute } }; 

Функция test предоставляет объект, предоставляющий API, необходимый для описания сценария. Первое, что нужно сделать, это перейти к URL-адресу входа. Затем заполните поля и нажмите кнопку. Наконец, проверьте, можем ли мы найти текст «Ленты новостей».

 module.exports = { 'Login test': function (client) { client .url('http://foobar.qux/login') .setValue('input[name="email"]', '[email protected]') .setValue('input[name="password]', 'p455w0rdZ') .click('button[type="submit"]') .assert.containsText('main', 'News feed') .end(); } }; 

Примечание: всегда используйте .end() для завершения списка инструкций, чтобы правильно завершить сеанс Selenium.

Это было довольно просто! Теперь мы можем запустить наш тест, чтобы увидеть, работает ли он:

 ./node_modules/.bin/nightwatch 

Это должно дать нам что-то вроде этого:

Реализация функционального тестирования JavaScript с Nightwatch.js

Примечание. С выпуском Firefox 47 перестала работать версия на основе расширений FirefoxDriver . Это было исправлено в Firefox 47.1 и Selenium 2.53.1 . Чтобы запустить тесты с использованием другого браузера, обратитесь к вики проекта .

И последнее, что мы можем сделать, чтобы избежать попадания в двоичный файл Nightwatch каждый раз, — это создать небольшой скрипт npm в package.json чтобы создать псевдоним:

 { "scripts": { "test": "nightwatch" } } 

Улучшение тестов Nightwatch

Наличие большого количества функциональных тестов может привести к появлению большого количества дублирующейся информации, что затрудняет обслуживание (да, наборы тестов также необходимо поддерживать). Чтобы предотвратить это, мы можем использовать Page Objects .

В мире сквозного тестирования методология Page Objects является популярным шаблоном, состоящим из упаковки проверенных страниц (или фрагментов страницы) в объекты. Цель состоит в том, чтобы абстрагироваться от базового HTML и общей конфигурации, чтобы упростить сценарии.

К счастью, в Nightwatch есть простой способ обработки объектов страницы. Первое, что нам нужно сделать, это добавить опцию page_objects_path в конфигурацию. Я чувствую, что tests/pages имеют смысл; Вы можете указать любую папку, которую хотите.

 module.exports = { src_folders: ['tests'], page_objects_path: 'tests/pages', selenium: SELENIUM_CONFIGURATION, test_settings: ENVIRONMENTS }; 

Теперь мы можем создать файл login.js в этой папке. Позже имя файла будет использоваться в качестве ключа для получения всей конфигурации, указанной в этом файле, поэтому я предлагаю дать ему разумное имя.

В этом файле мы укажем URL и псевдоним некоторых HTML-элементов с понятным именем, чтобы упростить написание будущих сценариев.

 module.exports = { url: function () { return this.api.launch_url + '/login'; }, elements: { emailField: 'input[name="email"]', passwordField: 'input[name="password"]', submitButton: 'button[type="submit"]' } }; 

Обратите внимание, что мы не жестко кодируем URL. Вместо этого мы используем опцию launchUrl определенную в конфигурации среды. Таким образом, наш объект страницы не зависит от контекста и будет работать независимо от среды.

Теперь довольно просто изменить наш тест для использования объекта страницы. Сначала нам нужно получить страницу через объект page от клиента. Каждый объект страницы представлен как функция, названная в честь имени файла объекта страницы (например, login() ).

Затем мы можем заменить наши селекторы CSS нашими псевдонимами, с префиксом символа @ чтобы указать, что мы ссылаемся на произвольное имя. Вот и все.

 module.exports = { 'Login test': (client) => { const page = client.page.login(); page.navigate() .setValue('@emailField', '[email protected]') .setValue('@passwordField', 'p455w0rdZ') .click('@submitButton') .assert.containsText('main', 'News feed'); client.end(); } }; 

Обратите внимание, как мы прекращаем сеанс на самом клиенте, а не на странице.

Работа с несколькими средами

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

Для запуска тестов в конкретной среде мы можем использовать параметр --env в CLI. Среда по default (уже в нашей конфигурации) используется, когда мы опускаем эту опцию.

Давайте добавим промежуточную среду в нашу конфигурацию.

 var STAGING_CONFIGURATION = Object.assign({}, DEFAULT_CONFIGURATION, { launch_url: 'http://staging.foobar.qux' }); var ENVIRONMENTS = { default: DEFAULT_CONFIGURATION, staging: STAGING_CONFIGURATION }; 

Теперь при запуске наших тестов опция launch_url будет отличаться в зависимости от среды.

 npm test --env staging 

Завершение дела

Давайте подведем итог всему этому. Nightwatch.js — это инфраструктура JavaScript, используемая для написания сквозных функциональных тестов. Он опирается на API Selenium WebDriver и может автоматически запускать разные браузеры.

Написание тестов в основном состоит из определения типичного пользовательского сценария. Для этого есть простой, но очень полный API.

Оттуда я оставлю это вам и призываю вас начать писать функциональные тесты для ваших крупнейших проектов, чтобы никогда больше не нарушать пользовательскую функцию!