Автор материала, перевод которого мы публикуем сегодня, сотрудник Welldone Software, говорит, что если в двух словах рассказать об инструментах для тестирования JavaScript-проектов, то для модульного и интеграционного тестирования рекомендуется использовать Jest, а для тестов пользовательского интерфейса — TestCafe. Однако каждый конкретный проект может нуждаться в чём-то особенном. Лучший способ найти именно то, что нужно — взять несколько инструментов, которые, как кажется, подойдут, и испытать их в действии. Эксперименты подскажут — на чём именно стоит остановиться.



Представляем вашему вниманию обзор наиболее широко используемых инструментов тестирования для JS-проектов, на которые стоит обратить внимание в 2018-м году.

Инструменты тестирования общего назначения


?Jsdom


Jsdom — это JavaScript-реализация WHATWG DOM и стандартов HTML. Другими словами, jsdom имитирует окружение браузера, не выполняя ничего кроме обычного JS.

В подобном окружении тесты могут выполняться очень быстро. Минус jsdom заключается в том, что не всё можно симулировать за пределами реального браузера (например, при таком подходе не получится делать скриншоты), поэтому использование данного средства ограничивает возможности тестирования.

Стоит упомянуть, что сообщество JS интенсивно работает над jsdom и совершенствует этот инструмент. Возможности его текущей версии очень близки к настоящему браузеру.

?Istanbul


Инструмент Istanbul позволяет анализировать покрытие кода модульными тестами. Он выводит детальные отчёты, ориентируясь на которые можно получить точное представление о том, что в проекте ещё не протестировано, и оценить объём работ, необходимый для улучшения ситуации.

?Karma


Karma позволяет запускать тесты в браузере и в средах, напоминающих браузеры, в том числе — в jsdom.
Karma поддерживает сервер тестирования со специальной веб-страницей, в окружении которой и будут выполняться тесты. Эту страницу можно открывать во множестве браузеров. Кроме того, это означает возможность удалённого проведения тестов с использованием сервисов вроде BrowserStack.

?Chai


Chai — это самая популярная библиотека для создания утверждений.

?Unexpected


Unexpected — это библиотека для создания утверждений, синтаксис которой немного отличается от Chai. Кроме того, эта библиотека расширяема, что позволяет создавать более продвинутые утверждения. В частности, речь идёт об использовании библиотек, основанных на unexpected, например таких, как unexpected-react, подробности о которой можно почитать здесь.

?Sinon.JS


Sinon.JS представляет собой мощную автономную систему, предоставляющую возможность выполнять тестирование JavaScript-проектов с использованием так называемых шпионов (spy), заглушек (stub) и имитаций (mock). Эта система умеет работать с любыми фреймворками для модульного тестирования.

?Testdouble.js


Testdouble.js — это менее популярная библиотека, выполняющая те же функции, что и Sinon, при этом её разработчики говорят о том, что она решает похожие задачи лучше, чем Sinon. Она отличается набором возможностей, некоторыми особенностями архитектуры и подходом к тестированию, что может сделать её полезной во многих ситуациях. Подробности о testdouble можно почитать здесь, здесь и здесь.

?Wallaby


Wallaby — это ещё один инструмент, достойный упоминания. Он не бесплатен, но многие пользователи полагают, что он стоит тех денег, что за него просят. Wallaby работает в IDE (поддерживаются все основные IDE) и выполняет тесты, соответствующие изменениям кода. Данные о результатах тестирования выводятся в реальном времени там же, где находится код.


Wallaby

?Cucumber


Cucumber помогает разработчикам с написанием тестов в BDD. Тесты разделены между файлами критериев приемлемости, подготовленных с использованием синтаксиса Gherkin, и собственно файлами тестов, которые им соответствуют. Тесты могут быть написаны на различных языках, которые поддерживает фреймворк, в том числе и на JS.

Вот пример файла like-article.feature:

Feature: A reader can share an article to social networks
  As a reader
  I want to share articles
  So that I can notify my friends about an article I liked
Scenario: An article was opened
    Given I'm inside an article
    When I share the article
    Then the article should change to a "shared" state

Вот пример файла like-article.steps.js:

module.exports = function() {
  this.Given(/^I'm inside an article$/, function(callback) {
    // код функционального инструмента тестирования
  })
  
  this.When(/^I share the article$/, function(callback) {
    // код функционального инструмента тестирования
  })
    
  this.Then(/^the article should change to a "shared" state$/, function(callback) {     
    // код функционального инструмента тестирования
  }) 
}

Многие команды находят этот синтаксис более удобным, чем TDD.

Фреймворки для модульного и интеграционного тестирования


Первое, что, вероятно, стоит выбрать при поиске подходящих инструментов тестирования — это фреймворк и библиотеки для его поддержки. Рекомендовано использовать то, что предоставляет выбранный фреймворк до тех пор, пока не возникнет необходимости в уникальных инструментах. Вот несколько общих рекомендаций:

  • Если вы ищете некую отправную точку, или вам нужен быстрый фреймворк для большого проекта — выбирайте Jest.
  • Если вас интересуют гибкость и расширяемость конфигурации — взгляните на Mocha.
  • Если вы стремитесь к простоте — попробуйте Ava.
  • Если вам нужен контроль над низкоуровневыми механизмами тестирования — обратите внимание на tape.

Вот краткий обзор наиболее известных инструментов из данной категории.

?Mocha


Mocha в настоящий момент является самой широко используемой библиотекой. В отличие от библиотеки Jasmine, о который мы ещё поговорим, эта библиотека применяет сторонние инструменты для построения утверждений и внешние средства для создания имитаций и функций-шпионов (обычно Enzyme и Chai). Это означает некоторые дополнительные сложности при настройке Mocha, и то, что получаемый функционал будет разделён между различными библиотеками, но этот фреймворк более гибок и расширяем в сравнении с Jasmine.

Например, если вам нужна особая логика утверждений, вы можете сделать форк Chai и заменить только Chai в своём наборе инструментов вашей собственной библиотекой для создания утверждений. Это можно сделать и в Jasmine, но в Mocha это изменение будет более очевидным.

Вот некоторые особенности Mocha, на которые стоит обратить внимание:

  • Сообщество. Силами сообщества разработано множество плагинов и расширений для использования в уникальных сценариях тестирования.
  • Расширяемость. Плагины, расширения и библиотеки, которые можно использовать с Mocha, такие, как Sinon, включают в себя возможности, которых нет в Jasmine.
  • Глобальные переменные. Mocha, по умолчанию, создаёт структуры теста в глобальном виде. Это не относится к утверждениям, имитациям, функциям-шпионам, что отличает Mocha от Jasmine. Некоторым кажется нелогичной подобная неоднородность глобальных объектов.

?Jest


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

Стоит отметить, что после анализа огромного количества материалов о Jest, мы можем сделать вывод о том, что многие разработчики впечатлены скоростью и удобством этого фреймворка. Среди особенностей Jest можно отметить следующие:

  • Производительность. В первую очередь стоит сказать о том, что фреймворк Jest признан самым быстрым в применении к большим проектам со множеством файлов тестов благодаря реализации интеллектуального механизма параллельного тестирования. Мы можем подтвердить это на собственном опыте, кроме того, вот, вот, вот и вот — материалы, поддерживающие наши выводы.
  • Пользовательский интерфейс. Интерфейс Jest отличается понятностью и удобством.
  • Наличие всего необходимого для начала работы. Jest поставляется со средствами создания утверждений, функций-шпионов и имитаций, которые эквивалентны отдельным библиотекам, вроде Sinon, выполняющим те же функции. Если стандартные возможности вас не устраивают и нужно что-то особенное, можно воспользоваться и сторонними библиотеками.
  • Глобальные переменные. Как и в случае с Jasmine, Jest, по умолчанию, создаёт глобальные переменные тестирования, поэтому их не нужно явно подключать. Эту особенность можно воспринимать и как недостаток, так подобный подход вредит гибкости тестов и возможностям по управлению ими, но в большинстве случаев это всего лишь упрощает работу:

    // "describe" уже в глобальной области видимости
    // поэтому данные команды импорта не требуются:
    // import { describe } from 'jest'
    // import { describe } from 'jasmine'
    
    describe('calculator', function() {
      ...
    })
    
  • Тестирование при помощи снимков. Существует библиотека jest-snapshot, которая разработана Facebook. Её, для организации тестирования с помощью снимков (snapshot testing), можно использовать практически в любом другом фреймворке, например, через подходящий плагин.
  • Улучшенная имитация модулей. Jest упрощает имитацию «тяжёлых» модулей, что позволяет улучшить скорость тестирования. Например, средствами Jest можно создать «заглушку» для некоего сервиса, выполняющего сетевой запрос, что даёт гораздо более высокую скорость в сравнении с реальным выполнением запроса.
  • Анализ покрытия кода тестами. В Jest имеются мощные и быстрые встроенные средства для анализа покрытия кода тестами, которые основаны на Istanbul.
  • Надёжность. Хотя Jest — это сравнительно молодая библиотека, в течение 2017-го года была проведена большая работа над её стабильностью, и теперь её можно считать надёжной. Сейчас её, например, поддерживают все основные IDE.
  • Разработка. В ходе разработки проекта тесты выполняются очень быстро за счёт того, что система отслеживает изменения файлов и не выполняет ненужных действий.

?Jasmine


Jasmine — это фреймворк для тестирования, на котором основан Jest. Если есть Jest — кому может понадобиться Jasmine? Всё дело в том, что Jasmine появился раньше, чем Jest, по нему имеется огромное количество публикаций, для него создано множество инструментов.

Кроме того, создатели Angular всё ещё советуют использовать именно Jasmine, а не Jest, хотя и Jest отлично подходит для выполнения тестирования Angular-проектов, и многие пользуются им для этого. Вот основные особенности Jasmine:

  • Наличие всего необходимого для начала работы. Jasmine включает в себя всё, что необходимо для того, чтобы приступить к тестированию.
  • Глобальные переменные. В Jasmine все важные средства тестирования доступны в глобальной области видимости.
  • Сообщество. Jasmine существует с 2009-го года, за это время вышло множество публикаций по этому фреймворку. Кроме того, создано немало инструментов, основанных на Jasmine.
  • Поддержка Angular. Все версии Angular поддерживают Jasmine, и именно этот фреймворк рекомендует официальная документация по Angular.

?Ava


Ava — это минималистичная библиотека для тестирования, поддерживающая параллельное выполнение тестов. Вот её основные характеристики:

  • Наличие всего необходимого для начала работы. Ava поставляется со всем, что нужно для начала тестирования (помимо средств для создания функций-шпионов и имитаций, которые несложно интегрировать в Ava). Тесты на Ava могут выполняться в среде Node.js. Тут используется следующий синтаксис для формирования структуры теста и построения утверждений:

    import test from 'ava'
    
    test('arrays are equal', t => {
      t.deepEqual([1, 2], [1, 2])
    })
  • Глобальные переменные. Как можно видеть из вышеприведённого фрагмента кода, библиотека не создаёт глобальных переменных, то есть разработчик может лучше контролировать происходящее.
  • Простота. Ava отличается простой структурой и простой моделью утверждений. Тут нет чрезмерно сложного API, но при этом поддерживается множество продвинутых возможностей.
  • Разработка. Ava удобно использовать в процессе разработки, так как система позволяет быстро тестировать изменённый код…
  • Скорость. Тесты выполняются параллельно в виде отдельных процессов Node.js.
  • Тестирование при помощи снимков. Эта возможность поддерживается как часть фреймворка.

?Tape


Tape — это самый простой из рассматриваемых здесь фреймворков для тестирования, имеющий небольшое и понятное API. Это — обычный JS-файл, который работает в Node.js. Вот основные характеристики tape:

  • Простота. Минималистичная структура тестов и утверждений, отсутствие сложного API. Тут всё устроено ещё проще, чем в Ava.
  • Глобальные переменные. Глобальные переменные не создаются, это даёт возможность лучше контролировать испытания.
  • Отсутствие общего состояния. Tape не приветствует использование функций вроде beforeEach, что отражает стремление к модульности тестов и к обеспечению максимального контроля над процессом тестирования.
  • Отсутствие необходимости в интерфейсе командной строки. Библиотека tape способна работать везде, где может выполняться JS.

Средства тестирования пользовательского интерфейса


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

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

  • Если вы ищете простой и надёжный универсальный инструмент, или некую отправную точку в деле поиска подходящего фреймворка — попробуйте TestCafe.
  • Если вы хотите идти в ногу со временем и пользоваться поддержкой сообщества разработчиков — взгляните на WebdriverIO.
  • Если вас не интересует кросс-браузерная поддержка — используйте Puppeteer.
  • Если в вашем приложении нет запутанных сценариев взаимодействия с пользователями и сложных интерфейсов, вроде страниц, полных форм и навигационных элементов — используйте кросс-браузерные инструменты без пользовательского интерфейса вроде Casper.

?Selenium


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

Возможностями Selenium можно управлять различными способами, используя множество языков программирования, а применение некоторых инструментов позволяет работать с Selenium и вовсе без программирования.

Нам, однако, интересна конфигурация, в которой сервер Selenium управляется с помощью Selenium WebDriver, который служит слоем взаимодействия между Node.js и сервером, который управляет браузером. Схему взаимодействия различных частей системы можно описать так:

Node.js <=> WebDriver <=> Selenium Server <=> FF/Chrome/IE/Safari

WebDriver можно импортировать в выбранный фреймворк для тестирования. Тесты можно писать с использованием возможностей по управлению браузером:

describe('login form', () => {
 
  before(() => {
    return driver.navigate().to('http://path.to.test.app/')
  })
  
  it('autocompletes the name field', () => {
    driver
      .findElement(By.css('.autocomplete'))
      .sendKeys('John')
    
    driver.wait(until.elementLocated(By.css('.suggestion')))
    
    driver.findElement(By.css('.suggestion')).click()
    
    return driver
      .findElement(By.css('.autocomplete'))
      .getAttribute('value')
      .then(inputValue => {
        expect(inputValue).to.equal('John Doe')
      })
  })
  
  after(() => {
    return driver.quit()
  })
  
})

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

Однако, тут нельзя не учитывать то, что существуют библиотеки, расширяющие возможности WebDriver, представленные либо его форками, либо обёртками для него.

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

Однако, если говорить о Selenium, многие предпочитают не использовать его напрямую. Взглянем на некоторые библиотеки, использующие возможности Selenium.

Appium


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


Итак, если вы используете инструменты, основанные на Selenium, вы можете применять Appium для тестирования мобильных проектов.

Protractor


Protractor — это библиотека-обёртка для Selenium, которая ориентирована на Angular. Вот основные особенности этой библиотеки:

  • Поддержка Angular. Protractor ориентирован на Angular, хотя эта библиотека может быть успешно использована и с другими JS-фреймворками. Официальная документация по Angular рекомендует именно эту библиотеку.
  • Отчёты об ошибках. Тут имеется удобный механизм создания отчётов.
  • Сообщество и технологии. В Protractor доступна поддержка TypeScript. Развитием библиотеки занимается огромная команда Angular.

WebdriverIO


WebdriverIO предлагает собственный подход к использованию функционала Selenium WebDriver. Эта библиотека предназначена для Node.js. Среди особенностей этого проекта можно выделить следующие:

  • Синтаксис. WebDriverIO отличается очень простыми и читабельными синтаксическими конструкциями.
  • Гибкость. WebDriverIO — гибкая и расширяемая библиотека.
  • Сообщество. Библиотека отличается хорошей поддержкой и полным энтузиазма сообществом разработчиков, усилиями которого созданы плагины и расширения, способствующие увеличению сферы использования WebDriverIO.

Nightwatch


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

  • Фреймворк. Nightwatch можно использовать как с другими фреймворками, так и как самостоятельный инструмент, что может быть особенно полезным, если функциональные тесты планируется выполнять именно его средствами, без привлечения других технологий.
  • Синтаксис. Nightwatch отличается очень простым и читабельным синтаксисом.
  • Поддержка и технологии. Тут нет поддержки TypeScript. Надо отметить, что возникает ощущение того, что эта библиотека пользуется несколько меньшей поддержкой, чем другие.

?TestCafe


TestCafe является отличной альтернативой инструментам, основанным на Selenium. Код этой библиотеки был открыт в конце 2016-го года. Надо отметить, что всё ещё существует платная версия TestCafe, которая предлагает средства для тестирования, не требующие программирования. Например — это инструменты для записи тестов. В рамках платной версии предлагается и поддержка пользователей. Надо отметить, что существует множество устаревших публикаций, которые вышли до открытия кода библиотеки и считают закрытый код её недостатком.

TestCafe внедряется в страницы в виде JS-скрипта, она не контролирует браузер, как это делает Selenium. Это позволяет TestCafe выполняться в любых браузерах, включая мобильные, и иметь полный контроль над тем, что происходит в JavaScript.

Библиотека TestCafe написана на JavaScript и ориентирована на тестирование. Она в настоящее время бурно развивается, хотя уже сейчас считается стабильной и имеющей достаточное количество возможностей. Рассмотрим её основные особенности:

  • Быстрая настройка рабочей среды. Пожалуй, можно говорить о том, что особой настройки рабочей среды для использования TestCafe не требуется. Достаточно открыть любой браузер и приступить к тестированию.
  • Поддержка различных браузеров, поддержка платформами для автоматизации тестирования. TestCafe поддерживает множество браузеров и устройств и может быть использована на платформах SourceLabs или BrowserStack, которые дают доступ к различным устройствам и браузерам. В частности, речь идёт о выполнении тестов в Chrome и Firefox без пользовательского интерфейса, о чём мы ещё поговорим.
  • Параллельное тестирование. TestCafe может выполнять тесты в нескольких экземплярах браузера одновременно. Такой подход может значительно уменьшить время тестирования.
  • Отчёты об ошибках. TestCafe содержит удобные средства для формирования отчётов об ошибках.
  • Экосистема. TestCafe использует собственную структуру тестов. Это может быть очень удобно, особенно учитывая то, что тесты пользовательского интерфейса обычно выполняются отдельно от других тестов, но нравится это далеко не всем.

    import { Selector } from 'testcafe';
    
    fixture `Getting Started`
        .page `https://devexpress.github.io/testcafe/example`
    
    // Собственная структура тестирования
    test('My first test', async t => {
        await t
            .typeText('#developer-name', 'John Smith')
            .click('#submit-button')
            .expect(Selector('#article-header').innerText)
            .eql('Thank you, John Smith!')
    })

?Cypress


Cypress — это прямой конкурент TestCafe. Этот фреймворк работает практически так же, внедряя тесты в код страниц, но он пытается делать это более современным, гибким и удобным способом. Cypress новее, этот фреймворк недавно перешёл из стадии закрытой бета-версии в общедоступную бета-версию (в октябре 2017), но многие уже им пользуются. Вот основные особенности Cypress:

  • Нет кросс-браузерной поддержки. В настоящий момент поддерживается лишь Chrome (и — не версия без пользовательского интерфейса). Сейчас ведётся разработка в направлении кросс-браузерной поддержки.
  • Отсутствие расширенных возможностей тестирования. Тут, в сравнении с TestCafe, пока не хватает возможностей параллельного тестирования и некоторых дополнительных инструментов, однако появление всего этого есть в планах разработчиков.
  • Документация. Cypress отличается хорошо написанной и понятной документацией.
  • Средства отладки. Здесь имеются удобные средства для отладки и логирования.
  • Использование Mocha. Mocha используется как источник структуры тестов. Это, для тех, кто привык к Mocha, означает возможность строить тесты пользовательского интерфейса так же, как и остальные тесты.

    describe('My First Cypress Test', function() {
      it("Gets, types and asserts", function() {
        cy.visit('https://example.cypress.io')
    
        cy.contains('type').click()
    
        // Тут должен быть новый URL, который включает '/commands/actions'
        cy.url().should('include', '/commands/actions')
    
        // Получает поле ввода, вводит в него данные и проверяет обновление значения.
        cy.get('.action-email')
          .type('fake@email.com')
          .should('have.value', 'fake@email.com')
      })
    })

?Puppeteer


Puppeteer — это библиотека для Node.js, которую разработала Google. Она предоставляет удобное Node.js API для управления браузером Chrome без пользовательского интерфейса.

Подобный браузер — это обычный Chrome v59+, который запускается с флагом --headless. Когда браузер выполняется в таком режиме, он предоставляет API для управления им, а Puppeteer — это, как уже было сказано, JS-инструмент, созданный Google для управления браузером.

Стоит сказать, что браузер Firefox также, в конце 2017-го, был выпущен с поддержкой работы в режиме без пользовательского интерфейса.

Обратите внимание на то, что различные инструменты для тестирования могут использовать Chrome и Firefox без пользовательского интерфейса. Например, это TestCafe и Karma.

Среди основных особенностей Puppeteer можно отметить следующие:

  • Сообщество. Puppeteer — инструмент сравнительно новый, но вокруг него уже сложилось большое сообщество, которое разрабатывает дополнительные средства для работы с ним.
  • Производительность. Puppeteer отличается высокой производительностью, он использует последнюю версию движка Chrome, что отличает его, например, от PhantomJS, который построен на более старом форке WebKit.
  • Отсутствие поддержки расширений. Основной недостаток Chrome без пользовательского интерфейса (и, соответственно, недостаток Puppeteer) заключается в том, что он не поддерживает расширения вроде Flash. Возможно, такой поддержки не появится и в ближайшем будущем.

?PhantomJS


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

С момента появления Puppeteer создатель PhantomJS, Виталий Слободин, прекратил работу над ним, в результате все процессы в сфере PhantomJS, с середины 2017, замедлились, хотя тут всё ещё наблюдается какое-то движение.

В каких ситуациях можно отдать предпочтение PhantomJS, если существует Puppeteer? Рассмотрим некоторые из них:

  1. Проект это гораздо более зрелый, по нему существует множество руководств, для него написано множество отличных инструментов.
  2. PhantomJS используется множеством полезных инструментов вроде CasperJS. Применяя эти инструменты, вы вынуждены будете использовать PhantomJS.
  3. В PhantomJS применяется не самая новая версия WebKit, что позволяет ему имитировать поведение старых версий браузеров Chrome.
  4. PhantomJS поддерживает расширения вроде Flash, а Chrome без пользовательского интерфейса — нет.

?Nightmare


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

Nightmare использует Electron, что делает эту библиотеку похожей на PhantomJS, однако, тут применяется более новая версия Chromium и библиотека активно поддерживается и разрабатывается. Этому способствует и тот факт, что главная цель проекта Electron, который так же динамично развивается, заключается в создании кросс-платформенных настольных приложений на базе JavaScript, HTML и CSS.

Кроме того, сейчас ведутся обсуждения и производятся эксперименты, направленные на применение в Nightmare Chrome без пользовательского интерфейса. Взглянем на код тестов на Nightmare в сравнении с кодом на PhantomJS.

Вот код тестов на Nightmare:

yield Nightmare()
  .goto('http://yahoo.com')
  .type('input[title="Search"]', 'github nightmare')
  .click('.searchsubmit')

Вот код тестов на PhantomJS:

phantom.create(function (ph) {
  ph.createPage(function (page) {
    page.open('http://yahoo.com', function (status) {
      page.evaluate(
        function () {
          var el = document.querySelector('input[title="Search"]')
          el.value = 'github nightmare'
        },
        function (result) {
          page.evaluate(
            function () {
              var el = document.querySelector('.searchsubmit')
              var event = document.createEvent('MouseEvent')
              event.initEvent('click', true, false)
              el.dispatchEvent(event)
            },
            function (result) {
              ph.exit()
            }
          ) // page.evaluate
        }
      ) // page.evaluate
    }) // page.open
  }) // ph.createPage
}) // phantom.create

?Casper


Casper — это средство, созданное на основе PhantomJS и SlimerJS (это то же самое, что и Phantom, но тут используется Firefox Gecko). Casper позволяет имитировать взаимодействие пользователя с веб-страницами, даёт возможность написания скриптов и тестовых механизмов в абстрактном виде, поддерживает асинхронные возможности при создании скриптов для Phantom и Slimer.

Библиотека Slimer получила широкое распространение, хотя и считалась экспериментальной. В конце 2017-го года была выпущена её бета-версия, 1.0.0-beta.1, которая использует новый Firefox без пользовательского интерфейса. В настоящее время ведётся работа по устранению мелких недочётов и по выпуску первого релиза Slimer.

Возможно, в ближайшем будущем, с выходом второго релиза, Casper перейдёт с PhantomJS на Puppeteer и станет отличным инструментом для тестирования и в среде Chrome, и в среде Firefox. Полагаем, за этим проектом стоит понаблюдать.

?CodeceptJS


CodeceptJS, как и рассмотренный выше CucumberJS, предоставляет дополнительный уровень абстракции над различными библиотечными API. Всё это направлено на то, чтобы разработчик взаимодействовал с тестами, основываясь на сценариях поведения пользователей.

Вот как выглядит работа с CodeceptJS:

Scenario('login with generated password', async (I) => {
  I.fillField('email', 'miles@davis.com');
  I.click('Generate Password');
  const password = await I.grabTextFrom('#password');
  I.click('Login');
  I.fillField('email', 'miles@davis.com');
  I.fillField('password', password);
  I.click('Log in!');
  I.see('Hello, Miles');
});

А вот некоторые библиотеки, которые могут быть задействованы при выполнении этого кода: WebDriverIO, Protractor, Nightmare, Appium, Puppeteer. О них мы уже говорили.

Если вам кажется, что представленный выше синтаксис соответствует вашим нуждам, советуем опробовать CodeceptJS.

Итоги


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

Уважаемые читатели! Чем вы пользуетесь для тестирования ваших JS-проектов?

Комментарии (8)


  1. sanchezzzhak
    19.02.2018 16:14
    +1

    Я пользуюсь таким набором
    1 Mocha+Chai
    2 Sinon
    3 Nock для заглушек http ответов + Faker для генерации данных
    4 Браузер тесты использую (безголовый хром) chrome-remote-interface + chrome-launcher


  1. bustEXZ
    19.02.2018 16:16

    А как же гермиона (hermione) от Яндекса :)


  1. nybkox
    19.02.2018 16:21

    Как же хорошо, что есть люди, которые пишут такие статьи.
    Спасибо, добавил в закладки, уверен не один раз ещё пригодиться.


  1. SlavikF
    19.02.2018 23:13

    Что скажете по поводу qUnit? Устарел и в 2018 году уже нет смысла использовать? Или есть варианты?


  1. SlavikF
    19.02.2018 23:14

    И подскажите, какой стэк можно использовать для тестирования такого сценария:
    — есть JS библиотека, которая собирает некоторую аналитику, отправляя GET запросы на сервер
    — нужно протестиорвать, что отправляется именно то, что должно
    — я так думаю, что нужно поднять localhost сервер, на который будут уходить эти GET запросы. И будет такой тестовый сценарий: 1) тест кэйс инициирует событие, которое отправляет данные (GET запрос) 2) localhost server получает этот запрос 3) тест кэйс сравнивает то, что было отправлено с тем, что получил сервер

    Есть ли какой-либо стэк, который уже поддерживает подобный сценарий?



  1. vba
    20.02.2018 15:40

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


  1. kirill3333
    20.02.2018 23:28

    Недавно делал доклад на нашем Нижегородском JS митапе youtu.be/cgS3ggRM5C4