Прості модульні тести 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, через API WP REST і вставляє їх назву з посиланням на публікацію в div.entry-content
.
Ви збираєтеся експортувати функцію, яка виконує всю роботу:
щоб ви могли використовувати його у своїх тестах у Jest.
Нарешті написання модульних тестів JavaScript за допомогою Jest!
Тепер можна починати писати контрольні роботи! Jest може знайти тести різними способами:
- якщо ім’я файлу
test.js
- або має префікс назви файлу, який він перевіряє, наприклад
main.test.js
- якщо це
.js
файли, розташовані в папці з назвою__tests__
Створіть __tests__
папку та всередині неї a 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
була викликана один раз.
Макетна вибірка в тестах Jest
Наступний набір тестів починається з
і всередині цього ми маємо ще одну функцію демонтажу:
unlike afterEach
this буде виконано після виконання всіх тестів у цьому describe
блоці. Оскільки наш файл JavaScript використовує fetch
для завантаження дописів, нам потрібно перевірити, чи він був викликаний і він повернув те, що ми запитували, тому ми будемо висміювати fetch
функцію:
Ми висміюємо перший Promise, який розв’язує відповідь, а другий – JSON-представлення даних. Ці дані подібні до тих, що ми отримуємо від WP REST API. Враховуючи, що нашому коду потрібні лише назва та посилання, ми знущаємося над цим.
Тест інтеграції JavaScript з Jest в асинхронному коді, який використовує вибірку
Тепер ми можемо написати тест за допомогою mocked fetch
. У цьому тесті є велика відмінність від інших модульних тестів JavaScript: це інтеграційний тест. Попередні тести, досліджені тут, просто переконалися, що компонент працює добре. Ми перевірили, що якщо глобальна змінна початкового стану не була визначена, наш компонент не відображатиметься. Це відрізняється від того, що ми збираємося перевірити, як працює вся система, коли визначено початкову змінну стану, таким чином запускаючи транзакцію даних і, нарешті, вставляючи заголовки дописів із їхніми посиланнями в документ.
З самого початку все інакше: анонімна функція, передана в, test
отримує done
параметр. Насправді це функція, яка буде викликана, коли ми закінчимо тест. Jest чекатиме, доки done
його не викличуть, перш ніж завершити тест. Якщо done
його ніколи не викликати, тест завершиться невдало з помилкою тайм-ауту. Це цікаво для нас, оскільки ми тестуємо код із використанням fetch
, що є асинхронною функцією.
Глобаль wpJestTests
визначено, і наш mocked document.querySelector
тепер повертає те, що нагадує елемент HTML, з навіть classList
і його add
дочірнім методом.
Телефонуємо wpJestTestsInit
і очікуємо, що закінчиться коректно. Тепер, оскільки він асинхронний, fetch
ми будемо використовувати process.nextTick
from Node.js. In Node.js — nextTick
це черга, яка запускатиметься після завершення всіх подій у поточному циклі подій. Це чудово, тому що тоді всі наші обіцянки будуть виконані, а це саме те, що нам потрібно для тестування цього коду, який включає fetch
.
Решта — це більше твердження, щоб переконатися, що querySelector
знайдено щось для роботи, що fetch
справді було викликано, що клас було додано до списку, і що заголовки та посилання наших публікацій були вставлені у відповідний елемент HTML. Коли все зроблено, ми викликаємо, done
і наш асинхронний тест закінчується.
Виконайте свої тести Jest
Тепер ви можете друкувати
npm run test
і Jest запустить модульні тести JavaScript для вашого плагіна WordPress
Висновок
Тож Jest — чудове та просте рішення для написання тестів, які охоплюють код JavaScript наших плагінів або тем WordPress. Але є ще щось. Якщо ми пишемо додаток React для нашого плагіна, ми можемо захотіти зробити твердження щодо нього. Jest також може допомогти певною мірою, і якщо нам потрібно більше, ми можемо додати Enzyme до наших інструментів і почати писати з ним інтеграційні тести.
Будь ласка, пожертвуйте!
Якщо ви вважаєте це корисним, не соромтеся пригостити мене кавою , щоб я міг не спати та створити для вас більше корисних посібників!
$3.00