Простые модульные тесты JavaScript в WordPress с Jest
WordPress имеет долгую историю модульного тестирования своего PHP-кода. Однако написание модульных тестов JavaScript и интеграционных тестов для кода в темах и плагинах не имеет такого же статуса. Давайте посмотрим, как протестировать JavaScript в наших плагинах и темах WordPress с помощью Jest.
Это содержание, которое мы рассмотрим в этой статье:
Модульные тесты JavaScript в WordPress
Так зачем же писать модульные тесты и интеграционные тесты? Они отлично гарантируют, что функция, метод класса или даже компонент React делают то, что они должны делать. Это помогает обнаруживать ошибки в коде, а также помогает сохранить целостность, когда позже в код вносятся изменения, проверяя, что он все еще работает должным образом после обновления.
Плагины и темы WordPress в основном написаны на PHP и могут использовать пакет PHPUnit для запуска тестов, создания утверждений, фиктивных функций и многого другого. В руководстве даже есть раздел, объясняющий, как быстро настроить модульное тестирование с помощью WP-CLI.
Для JavaScript в Справочнике есть страница о выполнении тестов QUnit, хотя она больше посвящена тестированию кода JavaScript в ядре WordPress.
Хотя ничего из этого не стандартизировано для JavaScript в WordPress, мы можем писать отличные модульные тесты, используя набор тестов Jest. В этой статье мы узнаем, как написать модульные тесты JavaScript для примера плагина, который загружает 5 сообщений через WP REST API с помощью fetch
функции из JavaScript и отображает их в определенном элементе DOM на странице.
Преимущества использования Jest для модульных тестов JavaScript в WordPress
В прошлом написание модульных тестов JavaScript включало настройку Mocha для запуска тестов, Chai для создания утверждений и Sinon для имитации функций и слежки за ними. Хотя они обеспечивают большую гибкость, работать с тремя пакетами гораздо сложнее, чем с одним. Jest предоставляет все это в одном пакете:
- вы можете запускать тесты, объявляя их с помощью
describe
иit
илиtest
- вы можете делать утверждения с помощью
expect
иtoBe
иtoHaveLength
многое другое - вы можете издеваться над функциями и шпионить за ними, и есть несколько способов сделать это
Прежде чем двигаться дальше
Чтобы эта статья была сосредоточена на тестировании с помощью Jest, есть дополнительные настройки, внешние по отношению к процессу тестирования, такие как Babel или Webpack, которые здесь не рассматриваются. Все это можно найти в репозитории WP Jest Tests, который сопровождает эту статью. Чтобы сохранить контекст, каждый раздел будет ссылаться на один из соответствующих файлов, которые мы напишем.
Обзор стороны PHP
Плагин PHP для примера, который мы будем использовать, чтобы научиться писать модульные тесты JavaScript, довольно стандартный. Единственные интересные строки — это когда мы ставим в очередь наш файл JavaScript и добавляем встроенный скрипт для передачи ему переменных:
После добавления файла JavaScript в очередь мы добавляем глобальную переменную wpJestTests
с расширением wp_add_inline_script()
. Эта переменная особенно интересна и сложна в работе, потому что она является внешней по отношению к нашему файлу JavaScript, и нам придется смоделировать ее в наших тестах.
Настройте тесты Jest
Сначала нам нужно инициализировать npm
наш проект плагина, чтобы иметь возможность установить Jest с ним. Перейдите в командной строке в папку вашего плагина и запустите:
npm init
и пройдите серию подсказок здесь
Отредактируйте созданный файл package.json и добавьте новую запись для запуска наших тестов в scripts
разделе:
"test": "jest"
Это будет команда, которую мы будем использовать, чтобы указать Jest запустить наши модульные тесты JavaScript. Это одноразовый запуск, но Jest также поддерживает просмотр файлов, поэтому вы можете ввести дополнительный:
"test-watch": "jest --watch"
Теперь установите Jest как зависимость для разработки, запустив
npm install -D jest
Во время установки создайте файл с именем jest.config.js
. Это будет содержать всю необходимую конфигурацию. Добавьте следующее:
module.exports = {
verbose: true,
setupFiles: [
'/__mocks__/globals.js'
],
moduleNameMapper: {
'.(css|less|sass|scss)$': '/__mocks__/styleMock.js'
}
};
Пройдемся по каждому:
verbose
: указывает, следует ли сообщать о каждом отдельном тесте во время выполнения. Все ошибки также будут отображаться внизу после выполнения. Обратите внимание, что если выполняется только один тестовый файл, по умолчанию он имеет расширениеtrue
.setupFiles
: список путей к модулям, которые запускают некоторый код для настройки или настройки среды тестирования. Каждый setupFile будет запускаться один раз для каждого тестового файла. Поскольку каждый тест выполняется в своей собственной среде, эти скрипты будут выполняться в среде тестирования непосредственно перед выполнением самого тестового кода. Мы будем использовать это для объявления глобальных переменных, отображаемых PHP и WordPress с помощью таких команд, какwp_add_inline_script
илиwp_localize_script
.moduleNameMapper
: это сопоставление регулярных выражений с именами модулей (или массивами имен модулей), которое позволяет заглушить статические ресурсы, такие как изображения или стили, с помощью одного модуля.
Вы наверняка заметили ссылку: это специальный токен, который Jest заменяет корнем вашего проекта, который обычно является местоположением вашего файла package.json
.
Мы углубимся в следующие два раздела, но сначала создадим папку и эти два файла, указанные выше:
- создать папку с именем
__mocks__
- внутри папки создайте файлы
styleMock.js
иglobals.js
Импорт фиктивных стилей для тестов Jest
Если, как и этот плагин, вы используете Webpack для компиляции всего, включая стили, и вы импортируете .scss
файл в .js
файл:
import './main.scss';
вам нужно использовать styleMock.js для имитации файлов SASS при их импорте в наш файл JavaScript, иначе Jest выйдет из строя, поскольку не сможет разрешить модуль. Вам не нужно много для этого файла, просто добавьте
Jest будет использовать этот макет каждый раз, когда найдет .scss
импорт, и сопоставит их с макетом, что позволит вам продвигаться вперед с тестами, не заботясь о стилях.
Настройте глобальные переменные для Jest
Давайте теперь поработаем с файлом globals.js. Одним из преимуществ использования Jest является то, что он уже поставляется с уже настроенной jsdom
реализацией веб-стандартов на чистом JavaScript, которая имитирует среду DOM, как если бы вы были в браузере, и мы будем использовать ее для имитации элементов DOM. для наших тестов.
Создайте папку __mocks__
и globals.js
файл внутри нее. Добавьте это в файл:
import { JSDOM } from 'jsdom';
const dom = new JSDOM();
global.document = dom.window.document;
global.window = dom.window;
global.window.wpJestTests = undefined;
Это объявит и имитирует некоторые объекты и методы, которые вы позже будете использовать в своих тестах. Последнее особенно интересно
global.window.wpJestTests = undefined;
Это глобальная переменная, которую мы написали, используя wp_add_inline_script
. Вам нужно смоделировать его как глобальную переменную, чтобы иметь возможность использовать ее в своих тестах.
Обзор файла JavaScript
Плагин WordPress имеет один файл JavaScript main.js в /src
папке. Позже это передается и выводится в /js/front.js
файл, который загрузит PHP. JavaScript загружает пять сообщений WordPress с fetch
помощью стандартной функции JavaScript через WP REST API и вставляет заголовок со ссылкой на сообщение в файл div.entry-content
.
Вы собираетесь экспортировать функцию, которая выполняет всю работу:
так что вы можете использовать его в своих тестах в Jest.
Наконец-то написание модульных тестов JavaScript с помощью Jest!
Теперь можно приступать к написанию тестов! Jest может найти тесты разными способами:
- если имя файла
test.js
- или имеет префикс имени файла, который он тестирует, например
main.test.js
- если это
.js
файлы, расположенные в папке с именем__tests__
Создайте __tests__
папку и внутри нее файл front.test.js
. Вы можете увидеть готовый файл JavaScript для тестов Jest в сопутствующем репозитории. Давайте пройдемся по блокам. Первая строка импортирует JS-файл, который мы хотим протестировать:
import { wpJestTestsInit } from '../src/main';
Затем мы очищаем все макеты, поэтому мы никогда не запускаем грязные макеты, несущие значения из предыдущих тестов. Это может привести к ошибкам, поскольку, например, если мы отслеживаем, сколько раз была вызвана фиктивная функция, мы можем получить неправильное чтение, если не очистим фиктивную функцию между тестом и тестом:
Первый тест, который мы напишем, делает основные утверждения, когда что-то терпит неудачу. Например, если глобальная wpJestTests
переменная, которую мы записывали wp_add_inline_script
, не была записана по какой-либо причине:
В этом коде
describe
создает группу, состоящую из нескольких связанных тестовtest
это то, что на самом деле выполняет тестexpect
обертывает наш объект тестирования, предоставляя доступ к ряду «сопоставителей», которые позволяют вам делать разные утверждения о его содержании.toBe
является одним из таких совпадений. В Jest включено множество сопоставителей, и есть даже другие, которые вы можете добавить с помощью стороннего пакета.
Первый тест ничего не определяет, wpJestTests
поэтому его значение будет таким, какое вы определили в globals.js
. Так как это undefined
, мы не можем работать, поэтому мы хотим подтвердить, что функция возвращается без каких-либо действий.
Второй тест определяет wpJestTests
и имитирует document.querySelector
возвращаемый метод, undefined
который он вернет, если не сможет найти элемент в DOM. В таком случае мы хотим подтвердить, что возвращаемся, ничего не делая, и что наша функция mocking document.querySelector
была вызвана один раз.
Mock fetch в тестах Jest
Следующий набор тестов начинается с
и внутри этого у нас есть еще одна функция разрыва:
в отличие от afterEach
этого, будет запущен после того, как все тесты внутри этого describe
блока будут выполнены. Поскольку наш файл JavaScript используется fetch
для загрузки сообщений, нам нужно убедиться, что он был вызван и вернул то, что мы запрашивали, поэтому мы собираемся смоделировать fetch
функцию:
Мы имитируем первое обещание, которое разрешается в ответ, а второе — в представление данных в формате JSON. Эти данные аналогичны тем, что мы получаем от WP REST API. Учитывая, что нашему коду нужны только заголовок и ссылка, мы издеваемся над этим.
Интеграционный тест JavaScript с Jest в асинхронном коде, который использует выборку
Теперь мы можем написать тест, используя mocked fetch
. Этот тест существенно отличается от других модульных тестов JavaScript: это интеграционный тест. Предыдущие тесты, рассмотренные здесь, просто гарантировали, что компонент работает хорошо. Мы проверили, что если глобальная переменная начального состояния не определена, наш компонент не будет отображаться. Это отличается, потому что мы собираемся проверить, как работает вся система, когда переменная начального состояния определена, тем самым запуская транзакцию данных и, наконец, вставляя заголовки сообщений со ссылками на них в документ.
С самого начала все по-другому: анонимная функция, переданная в, test
получает done
параметр. На самом деле это функция, которая будет вызываться, когда мы закончим тест. Jest будет ждать, пока done
не будет вызвана перед завершением теста. Если done
никогда не вызывается, тест завершится с ошибкой тайм-аута. Это интересно для нас, так как мы тестируем код, включающий fetch
, который является асинхронной функцией.
Глобальный объект wpJestTests
определен, и document.querySelector
теперь наш mocked возвращает то, что напоминает элемент HTML, с четным classList
и его add
дочерним методом.
Мы звоним wpJestTestsInit
и ожидаем, что он закончит его правильно. Теперь, поскольку он асинхронный, fetch
мы собираемся process.nextTick
использовать Node.js. In nextTick
Node.js — это очередь, которая будет запущена после завершения всех событий в текущем цикле событий. Это здорово, потому что тогда все наши промисы будут разрешены, а это именно то, что нам нужно для тестирования этого кода, включающего fetch
.
Остальное — больше утверждений, чтобы убедиться, что querySelector
найдено что-то для работы, что fetch
действительно было вызвано, что класс был добавлен в список, и что заголовки и ссылки наших сообщений были вставлены в соответствующий элемент HTML. Как только все это сделано, мы вызываем done
и наш асинхронный тест заканчивается.
Запустите тесты Jest
Теперь вы можете ввести
npm run test
и Jest запустит модульные тесты JavaScript для вашего плагина WordPress.
Вывод
Таким образом, Jest — отличное и простое решение для написания тестов, которые охватывают код JavaScript наших плагинов или тем WordPress. Но есть еще кое-что. Если мы пишем приложение React для нашего плагина, мы можем захотеть сделать утверждения об этом. Jest тоже может помочь в определенной степени, и если нам нужно больше, мы можем добавить Enzyme в наши инструменты и начать писать интеграционные тесты с его помощью.
Пожалуйста пожертвуйте!
Если вы нашли это полезным, не стесняйтесь купить мне кофе , чтобы я мог бодрствовать и создавать для вас больше полезных руководств!
$3.00