Всего несколько лет назад тестирование веб-сайтов было малоизведанной территорией, куда забредали лишь самые отважные разработчики. Не было ни инструментов, ни документации, ни даже общего понимания, что и как делать.
Сейчас все изменилось. Тестирование стало неотъемлемой частью веб-разработки и, самое главное, оно стало удобным. Например, исследование The State of JavaScript показало, что пользователи фреймворка Jest удовлетворены им на 96%!
Тестирование в вебе – это легко и нестрашно, сейчас вы в этом убедитесь.
Типы тестов
Модульные, или юнит-тесты
Работают с отдельными блоками (модулями) кода, например, функциями или классами. Они проверяют, что при определенных входных данных результат работы соответствует ожидаемому
Чтобы модули кода было проще тестировать, используйте чистые функции и другие приемы функционального программирования.
Интеграционные тесты
Иногда модули по отдельности работают корректно, но их взаимодействие происходит не так, как ожидалось. Интеграционные тесты работают с целыми процессами, проверяя правильность взаимодействия отдельных модулей и побочные эффекты.
Кроме того в реальном мире далеко не все единицы программы можно протестировать отдельно, и здесь тоже приходит на помощь интеграционное тестирование.
Этот уровень сложнее, чем юнит-тестирование, поэтому здесь часто используются вспомогательные инструменты, такие как моки/стабы/шпионы (подробнее про них будет дальше).
К этой же группе тестов относятся снепшоты.
Сквозные, или end-to-end тесты
E2E-тесты работают по принципу черного ящика, игнорируя внутреннюю структуру приложения. Их задача протестировать функционирование сценариев в целом, глазами пользователя.
Для этих тестов используются специальные инструменты имитации действий пользователя – контроллеры браузеров (о них чуть позже).
Многие сервисы предоставляют устройства и браузеры для запуска e2e-тестов.
Узнать больше:
Запуск тестов
Способ #1
Тесты подключаются как JS-скрипты на html-страницу и выполняются прямо в браузере.
Способ #2
Запуск в headless-браузере, без реального рендеринга на экране. Удобно и быстро, можно запускать даже из командной строки.
Способ #3
Запуск в Node.js. В этом случае придется имитировать DOM-структуру страницы с помощью специальных инструментов, например, библиотеки jsdom.
Задачи тестирования
Тестирование – это огромная сфера разработки, которая включает в себя множество задач. Различные инструменты могут решать лишь одну из них или же сразу несколько. Чаще всего для тестирования разработчик использует комбинацию таких инструментов.
Запуск тестов
Создание среды для запуска тестов (в браузере или Node.js) и ее настройка. Инструменты этой группы позволяют указать набор браузеров для тестирования, плагины, которые нужно использовать, способ форматирования результатов и т. д.
Пример для Karma:
Инструменты: Karma, Jasmine, Jest, TestCafe, Cypress, webdriverio
Структура тестов
Организация отдельных тестов в группы для удобства чтения и простого масштабирования.
Инструменты: Mocha, Jasmine, Jest, Cucumber, TestCafe, Cypress
Функции утверждения
Различные способы проверить, возвращает ли тест именно то значение, которое вы ожидаете.
Инструменты: Chai, Jasmine, Jest, Unexpected, TestCafe, Cypress
Вывод результатов
Удобный вывод результатов тестирования с указанием на ошибки.
Инструменты: Mocha, Jasmine, Jest, Karma, TestCafe, Cypress
Изоляция части кода
Очень часто тестируемая часть кода крепко связана с другими процессами, и ее необходимо выделить и изолировать. Для этого используются различные фейковые элементы – моки (mocks) и стабы (stubs, заглушки), которые имитируют нужную структуру или поведение.
Кроме этого существуют еще шпионы (spies), которые присоединяются к реальному коду и контролируют его работу. Они могут считать количество вызовов функции или запоминать ее входные параметры.
Пример мока в Sinon – создание поддельного сервера для обеспечения автономных, быстрых и ожидаемых ответов:
Пример стаба, который гарантирует, что методы user.isValid
всегда будет возвращать true
:
Пример шпиона для Sinon:
Инструменты: Sinon, Jasmine, enzyme, Jest, testdouble
Снепшоты (snapshots)
Моментальные снимки модулей, которые можно сравнивать между собой для обнаружения изменений между разными версиями.
Компонент здесь на самом деле не рендерится, но его внутренние данные сохраняются в отдельном файле, например:
Если при следующем тесте снимок будет отличаться, разработчик увидит сообщение:
Снимки обычно делаются для сравнения представления компонентов, но они также могут сравнивать другие типы данных, например, состояния в redux.
Покрытие кода
Создание отчетов о том, какая часть кода покрыта тестами.
Инструменты: Istanbul, Jest, Blanket
Контроллеры браузера
Имитация действий пользователя в браузере для проведения функциональных тестов.
Существует несколько способов управления браузерами. Некоторые инструменты устанавливают поверх них драйверы, например, selenium:
Your code on Node.js <> WebDriver <> FF/Chrome/Safari Driver <> Browser
Другой способ – внедрение скриптов, имеющих доступ ко всей среде приложения. Например, вот так выглядит имитация щелчка:
document.getElementByID('someButton').dispatchEvent(clickEvent)
И наконец, можно использовать для управления собственный API браузера, как это делает puppeteer:
Your code on Node.js <> Browser's API
Инструменты: Nightwatch, Nightmare, Phantom, Puppeteer, TestCafe, Cypress
Визуальная регрессия
Сравнение изображения веб-страницы с изображениями предыдущих версий.
Инструменты визуального регрессионного тестирования могут быть настроены для автоматического интеллектуального сравнения скриншотов. Эти скриншоты обычно делаются в рамках функциональных тестов или в отдельном сеансе автоматизации браузера.
Инструменты: Applitools, Percy, Wraith, WebdriverCSS
Чтобы начать тестировать ваш код, вы должны выбрать структуру тестирования и стиль утверждений, а также решить, как будут запускаться тесты.
Некоторые фреймворки (Jest, Jasmine, TestCafe, Cypress) предоставляют всю эту функциональность из коробки. Другие решают лишь одну-две задачи, поэтому их нужно комбинировать. Одна из самых популярных комбинаций для веб-тестирования: mocha + chai + sinon.
Имеет смысл отделить друг от друга тесты разных типов. Модульные и интеграционные тесты могут выполняться на лету, в "режиме наблюдения". А вот функциональные e2e-тесты обычно занимают больше времени, особенно при запуске в разных браузерах, поэтому их стоит выделить в отдельный процесс и запускать, например, непосредственно перед сохранением изменений в репозиторий.
Полезные инструменты
На данный момент существуют десятки замечательных инструментов для тестирования веб-приложений, большинство из них с открытым кодом. Мы рассмотрим лишь самые популярные.
jsdom
Эта библиотека имитирует браузерную среду (с DOM и HTML) исключительно методами JS.
Позволяет выполнять тесты намного быстрее, но покрывает не все возможности реальных браузеров.
Впрочем, сообщество активно совершенствует jsdom, и для большинства задач тестирования вам ее точно хватит.
Storybook
Storybook – это не инструмент тестирования как такового, однако он стимулирует создавать изолированные компоненты, которые легко тестировать. А с помощью Chromatic, о которой мы еще поговорим, вы фактически можете протестировать компоненты из своей storybook.
Testing Library
Простые и очень удобные утилиты для тестирования на различных платформах (React, Preact, React Native, Angular, Vue, Svelte и Marko). Хорошо интегрируются с другими инструментами тестирования, например, Cypress, Puppeteer, Testcafe и Nightwatch.
Electron
Платформа Electron позволяет писать кросс-платформенные десктопные приложения на JS + HTML + CSS. У него также есть headless-режим. Ряд инструментов, например, Cypress.io, используют Electron для запуска тестов с максимальными контролем браузера.
Istanbul
Формирует отчеты о покрытии кода модульными тестами для каждого оператора, строчки, функции и т.д.
Karma
Создает тестовый сервер для запуска тестов на веб-странице, которую можно запустить в большинстве браузеров, в том числе в headless-режиме, а также в браузерных средах вроде jsdom.
Chai
Самая популярная библиотека утверждений с большим количеством расширений.
Unexpected
Еще одна библиотека утверждения с немного другим синтаксисом и возможностью расширения. На его базе создана библиотека unexpected-react, для тестирования React-приложений.
Sinon.JS
Предоставляет большой набор мощных шпионов, моков и стабов для любого фреймворка модульного тестирования JavaScript-кода.
testdouble.js
Менее популярный аналог Sinon.
Wallaby
Платный инструмент для запуска тестов прямо в IDE (поддерживает все популярные среды) в режиме реального времени.
Cucumber
Этот фреймворк реализует BDD-подход и позволяет писать человекопонятные тесты на различных языках.
Описание фичи:
Возможно, этот синтаксис покажется вам более удобным, чем TDD.
Фреймворки для модульного и интеграционного тестирования
Jest
Простой, интуитивно понятный фреймворк от Facebook с большими возможностями. Если вы хотите "просто начать тестировать", выбирайте его – не ошибетесь.
Изначально Jest был основан на другом фреймворке – Jasmine, но со временем большая часть функциональности была переписана и появилось много новый фич.
Основные плюсы:
- Jest использует интеллектуальный механизм параллельного тестирования, за счет которого он работает максимально производительно, что особенно важно для больших проектов.
- Понятный интерфейс.
- Все, что необходимо для тестирования, поставляется "из коробки". Тут уже есть библиотека утверждений, шпионы и моки.
- Как и Jasmine, Jest создает глобальные переменные для функций тестирования по умолчанию, так что вам не нужно импортировать, например, функцию
describe
в каждый файл с тестами. Конечно, это можно расценивать как плохую практику, но в большинстве случаев, она упрощает вашу жизнь. - Создание снепшотов. Удобная библиотека jest-snapshot от Facebook может использоваться не только с Jest, но и многими другими фреймворками как плагин.
- Простое создание моков.
- Встроенный инструмент для отслеживания покрытия кода, основанный на Istanbul.
- Надежность. Jest используется во множестве больших и сложных проектов.
- Отличная поддержка всеми современными IDE.
- Удобная разработка. Работая в режиме наблюдения, jest обновляет только те тесты, которые могли измениться.
jasmine
Фреймворк с большой историей (с 2009) и огромным сообществом и базой знаний.
Основные плюсы:
- Предоставляет все, что нужно для начала тестирования.
- Создает глобальные переменные для всех важных функций тестирования по умолчанию.
- Тесная интеграция с Angular. Официальная документация Angular рекомендует именно Jasmine в качестве инструмента для тестирования.
mocha
Если вы ищете очень гибкий и расширяемый инструмента для тестирования, выбирайте Mocha.
В отличие от Jasmine, она не предлагает полный набор тестировщика из коробки. Чаще всего используется в связке с Sinon и Chai. Отсюда следует, что начать работать с этой библиотекой несколько труднее, однако это неудобство вполне компенсируется ее возможностями.
Основные плюсы:
- Огромное сообщество и большое количество плагинов на любой вкус.
- Невероятная расширяемость.
AVA
Если вы хотите тестировать максимально просто, обратите внимание на Ava. Это минималистичная библиотека с параллельным выполнением тестов.
Основные плюсы:
- Все, что нужно для начала работы (кроме шпионов и заглушек, которые легко добавить)Ready-To-Go- Comes with everything you need to start testing (besides spying and dubbing that you can add easily). Uses the following syntax for test structure and assertions, and runs in Node.js:
- Создание глобальных переменных по умолчанию.
- Очень простой синтаксис.
- В режиме наблюдения обновляет только изменившиеся тесты.
- Высокая скорость благодаря параллельному запуску тестов в разных процессах Node.js.
- Поддержка тестирования снепшотов.
tape
Если вы хотите по-настоящему низкоуровневый инструмент, tape – это то , что вам нужно. Это самая простая библиотека тестирования из рассмотренных – он состоит из одного JS файла с простейшим API .
Основные плюсы:
- Простота – даже проще, чем Ava.
- Создание глобальных переменных по умолчанию.
- Нет разделяемого состояния между разными тестами. Tape не использует функции, вроде
beforeEach
, чтобы обеспечить максимальную модульность теста. - Легко запускается везде, где может быть запущен JS.
Инструменты функционального тестирования
Инструменты для функционального тестирования очень сильно отличаются друг от друга по реализации, философии и API, поэтому следует потратить некоторое время, чтобы разобраться и попробовать разные решения.
selenium
Selenium и основанные на нем инструменты популярны и любимы разработчиками уже много лет. Они не предназначаются конкретно для функционального тестирования и могут применяться для любых целей, когда требуется контролировать поведение браузера. Для этого используются специальные драйверы.
Node.js <=> WebDriver <=> FF/Chrome/IE/Safari drivers <=> browser
Вы можете импортировать библиотеку Selenium WebDriver в ваш фреймворк для тестирования и использовать ее в тестах:
Можно использовать WebDriver как есть, однако существует множество библиотек, написанных поверх него, которые могут показаться вам более удобными.
Protractor
Protractor – это обертка над Selenium с улучшенным синтаксисом.
Основные плюсы:
- Тесная интеграция с Angular, специальные хуки для удобства тестирования.
- Удобный механизм отчета об ошибках.
- Поддержка TypeScript.
WebdriverIO
Библиотека с собственной реализацией Selenium WebDriver.
Основные плюсы:
- Простой синтаксис.
- Гибкость и расширяемость.
- Большое сообщество разработчиков и отличная поддержка.
- Поддержка библиотеки для визуального регрессионного тестирования Applitools.
Nightwatch
Nightwatch также использует собственную реализацию Selenium WebDriver, а также собственный фреймворк тестирования с тестовым сервером, утверждениями и набором инструментов.
Основные плюсы:
- Можно использовать как с другими фреймворками, так и самостоятельно.
- Простой, легко читаемый синтаксис.
Nightwatch не поддерживает Typescript.
Appium
Appium предоставляет схожий с Selenium интерфейс для тестирования веб-сайтов на мобильных устройствах с использованием следующих инструментов:
- iOS 9.3+: Apple’s XCUITest
- до iOS 9.3: Apple’s UIAutomation
- Android 4.2+: Google’s UiAutomator/UiAutomator2
- Android 2.3+: Google’s Instrumentation. (Instrumentation выделен в отдельный проект, Selendroid)
- Windows Phone: Microsoft’s WinAppDriver
TestCafe
Если вы хотите просто начать тестировать с минимальными трудностями, используйте TestCafe. Это отличная альтернатива инструментам, основанным на Selenium.
Библиотека использует другой способ реализации контроля над браузером – внедрение JavaScript-скриптов. Вы получаете полный контроль над циклом выполнения JavaScript.
Основные плюсы:
- Легко устанавливается через npm.
- Работает в любых браузерах (в том числе headless) и на любых устройствах. Библиотеку можно использовать вместе с SauceLabs или BrowserStack, которые предоставляют браузеры для тестирования.
- Параллельное тестирование в нескольких браузерах сразу.
- Удобные отчеты об ошибках.
- Собственная экосистема. Библиотека использует собственную структуру тестов. В большинстве случаев это вполне удобно, так как обычно UI-тесты запускаются отдельно от других.
Cypress
Если вам нужен удобный интерфейс, понятная документация, отличный набор инструментов и вообще швейцарский нож функционального тестирования – вам нужен Cypress.io.
Cypress делает то же самое, что и TestCafe, более современным и гибким способом. Разница заключается в том, что Cypress запускается прямо в браузере и оттуда контролирует ваши тесты, а TestCafe запускается в Node.js и контролирует тесты, внедряя скрипт в браузер и связываясь с ним.
Это относительно молодой инструмент (публичная бета-версия вышла в Октябре 2017), но у него уже большое сообщество почитателей.
Основные плюсы:
- Параллельное тестирование с версии 3.10.
- Полная и понятная документация.
- Нативный доступ ко всем переменным приложения без сериализации (в отличие от TestCafe, которая использует JSON-формат для передачи данных).
- Удобные инструменты запуска и дебаггинга.
- Кросс-браузерность.
- Постоянное развитие и добавление новых кейсов использования.
- В качестве поставщика структуры тестов используется Mocha, поэтому ваши функциональные тесты не будут сильно отличаться от остальных.
Puppeteer
Node.js библиотека от Google с понятным интерфейсом, которая использует Chrome или Headless Chrome.
Puppeteer не предлагает собственную систему тестирования, поэтому для создания необходимой среды и структуры могут использоваться уже рассмотренные инструменты, например, mocha и chai.
Основные плюсы:
- Поддержка команды Google и огромное сообщество разработчиков.
- Высокая производительность.
Playwright
Кроссбраузерный аналог Puppeteer от Microsoft.
Библиотека совсем новая (запущена в январе 2020), поэтому в ближайшем будущем могут появиться критические изменения.
CodeceptJS
Codecept предоставляет еще один уровень абстракции над API различных библиотек для создания человекопонятных тестов, фокусирующихся на поведении пользователя (как рассмотренный выше CucumberJS).
Этот код может работаться со многими из рассмотренных выше библиотек: WebDriverIO, Protractor, Nightmare, Appium, Puppeteer и даже Playwrigh.
Инструменты визуального регрессионного тестирования
Основные составляющие инструментов визуального регрессионного тестирования:
- Методы и интеграции для автоматизации браузера или для запуска в составе инструментов функционального тестирования (рассмотрены в предыдущем разделе).
- Создание "умных" скриншотов в виде изображений и снимков DOM.
- Методы сравнения изображений и DOM для выявления различий. Иногда для решения этой задачи используются продвинутые алгоритмы искусственного интеллекта.
- Пользовательский интерфейс для настройки сравнения.
На рынке уже достаточно много инструментов для визуального тестирования, но потенциал этой сферы все еще колоссальный. К сожалению, на данный момент бесплатные версии сильно проигрывают в качестве платным.
Applitools
Основные плюсы:
- Простая установка.
- Использует искусственный интеллект для сравнения снимков, а также человеческий ввод для определения различий.
- Легко интегрируется со многими рассмотренными выше инструментами.
- Есть бесплатный тариф, а также гибкая система платных.
Percy
Основные плюсы:
- Легко настраивается.
- Использует интеллектуальные методы сравнения снимков.
- Удобный человеческий ввод для определения различий.
- Легко интегрируется со многими рассмотренными выше инструментами.
- Гибкая система тарифов, включая бесплатный.
Happo
Платный инструментов визуального регрессионного тестирования, который подключается к CI для сравнения представлений компонентов интерфейса до и после изменений.
Поддерживает разные браузеры и разные разрешения для тестирования адаптивного дизайна.
Для open source проектов есть бесплатный тариф.
LooksSame
LooksSame – разработка Яндекса. Эта библиотека намного проще, чем рассмотренные выше платные инструменты, но для простых сайтов ее может быть достаточно.
Кроме того, ее можно использовать отдельно только для сравнения изображений, которые вы можете создавать любым удобным способом.
BackstopJS
Утилита для визуального регрессионного тестирования с открытым исходным кодом. Использует Headless Chrome и Puppeteer. Поддерживает CI.
AyeSpy
Еще одна open source утилита, которая использует selenium docker для проведения тестов в Chrome / Firefox.
reg-suit
Библиотека с открытым кодом, которая умеет сравнивать изображения, генерировать отчеты и сохранять их в облаке. Очень удобный подход, если вы хотите добавить визуальные регрессионные тесты к уже существующим функциональным тестам. Просто добавьте в настроенный процесс еще один шаг – создание скриншотов.
Differencify
Эта библиотека использует Puppeeteer и легко интегрируется с Jest snapshots. Может запускаться в docker.
Функциональное тестирование без кодинга
testim
Testim открывает ваше приложение и записывает все ваши действия, формируя из них тестовый сценарий. Использует машинное обучение, поддерживает разные браузеры и хорошо интегрируется со многими CI инструментами.
Гибкая система тарифов, есть бесплатная версия.
Chromatic
Инструмент визуального тестирования для Storybook.
Рендерит UI каждой истории и создает визуальный снепшот для последующего сравнения.
Теперь вы знакомы с основными терминами и инструментами веб-тестирования. Их очень много, и вы точно найдете те, что идеально подходят для вашего проекта. Не бойтесь пробовать!
Комментарии