Вступ в тестування front end коду

19

Від автора: коли і як використовувати різні варіанти тестування коду front end? Безліч розробників до цих пір не вміють тестувати front end код. Враховуючи постійне ускладнення front end розробки і те, що розробники відповідальні за стабільність, як ніколи раніше, front end тестування повинно ввійти до вас у звичку. Ми розберемо різні варіанти тестування і пояснимо, в яких ситуаціях їх краще всього застосовувати.

Front end тестування – загальний термін, що покриває різні стратегії автоматизованого тестування. Деякі з них, як наприклад юніт тести і інтеграційне тестування, вже довгі роки вважаються хорошою практикою серед back end розробників. Інші стратегії новіше і випливають із змін, в які перетворилася front end і back end розробка зараз.

До кінця статті ви точно будете знати, які стратегії тестування краще всього підходять вашій команді і кодом. Приклади в статті будуть написані на фреймворку Jasmine, але правила і процес схожі з більшістю фреймворків для тестування.

1. Юніт-тестування

Юніт-тестування – один з ветеранів тестування – самий нижній рівень тестування. Його завдання перевіряти, що маленькі шматочки коду (юніти) функціонують незалежно і, як очікується.

Уявіть, у вас є набір лего для створення будинку. Перед будівництвом будинку ви перевіряєте, що в наборі є всі частини (5 червоних квадратів, 3 жовтих прямокутника). Юніт тести перевіряють, що окремі шматочки коду – валідація полів і обчислення – працюють, як передбачається, ще до створення великої функції.

Мантра «роби добре щось одне» допомагає думати про юніт тестах. Якщо у вас є шматок коду з єдиною функціональністю, для нього необхідно написати юніт тест.

Розберемо код нижче. Це юніт тест простого калькулятора:

describe(«Calculator Operations», function () {
it(«Should add two numbers», function () {
Calculator.init();
var result = Calculator.addNumbers(7,3);
expect(result).toBe(10);
});
});

У додатку Calculator необхідно, щоб обчислення завжди функціонували незалежно. У коді вище ми перевіряємо, що ми завжди можемо складати точно два числа.

Спершу ми описуємо серію необхідних тестів з допомогою Jasmine describe. Так створюється тест сьют – група тестів для певної області застосування. Для програми калькулятор ми будемо групувати всі тести обчислень у свій сьют.

Сьюти добре підходять не тільки для організації коду, вони також дозволяють запускати цілі сьюти тестів. Якщо ви працюєте над новою функцією для програми, ви не хочете запускати всі тести при розробці, так як це забере багато часу. Окреме тестування сьютов дозволяє швидше писати код.

Далі ми пишемо самі тести. У функції it ми пишемо функцію або шматок функціональності для тестування. У нашому прикладі перевіряється функція додавання, тому ми будемо запускати сценарії, які підтверджують правильність роботи.

Далі йдуть перевірки в тесті – саме тут ми перевіряємо наш код на очікуваний результат. Ініціалізується калькулятор і запускається функція addNumbers з двома параметрами для складання. Значення виконання додавання ми поміщаємо в result і порівнюємо його на рівність з очікуваним числом (у нашому випадку 10).

Якщо addNumbers поверне інше число, наш тест провалиться. Ми напишемо подібні тести для інших обчислень – віднімання, множення і т. д.

2. Приймальні тести

Юніт тести – це перевірка всіх деталей лего, а приймальні тести – це перевірка всіх етапів будівництва на завершеність. Якщо є всі деталі, це не означає, що інструкції здійсненні і дозволять побудувати кінцеву модель.

Приймальні тести проводяться на запущеному додатку і перевіряють, щоб спроектовані дії, користувальницький введення і потік були завершеними і правильно функціонували.

Якщо функція addNumbers нашого додатка повертає правильне число, це не означає, що інтерфейс калькулятора буде працювати точно, як очікується. Якщо кнопки неактивні, або результат обчислень не відображається? Приймальні тести допомагають відповісти на ці питання.

describe(«Sign Up Failure state», function () {
it(«shouldn’t allow signup with invalid information», function () {
var page = visit(«/home»);
page.fill_in(«input[name=’email’]», «Not An Email»);
page.click(«button[type=submit]»);
page.click(«button[type=submit]»);
expect(page.find(«#signupError»).hasClass(«hidden»)).toBeFalsy();
});
});

Структури схожа на юніт тест: визначається сьют з допомогою describe, далі пишеться тест всередині функції it, після чого виконується код і перевіряється результат.

Тут не перевіряються певні функції і значення, тут ми перевіряємо правильність роботи сценаріїв (сценарій реєстрації) при неправильному заповненні. У коді вище виконуються більш дрібні дії, такі як перевірки форми, які можна винести в юніт-тести, а також будь-обробки для того, що відображає наш стан про помилку (элементс ID signupError).

Приймальні тести – чудовий спосіб перевірити ключові сценарії на правильність роботи. Також легко можна додати тести по крайніх випадках і допомогти QA командам знайти їх в додатку.

Перш ніж приймати рішення, що враховувати в приймальному тестуванні, послухайте користувачів. Як користувачі взаємодіють з вашим сайтом, що очікується в цій взаємодії? У цьому відмінність від юніт-тестування, яке краще підходить для перевірки функцій вимог (вимоги валідації полів).

3. Візуальний регрес

Як було згадано на початку, деякі типи тестування унікальні для front end. Перший такий тип – візуальний регрес. Він не тестує код, а порівнює отрендереный результат коду –інтерфейс – з рендер версією програми у production, staging і pre-changed.

Робиться це шляхом порівняння скріншотів, знятих з браузера без оболонки (браузер з сервера). Далі інструменти порівняно зображень знаходять найдрібніші відмінності між двома кадрами.

У PhantomCSS ваші тести вказують місце, куди необхідно переміститися, зняти скріншот, а фреймворк показує відмінності.

casper.start(«/home»).then(function(){
// Initial state of form
phantomcss.screenshot(«#signUpForm», «sign up form»);
// Hit the sign up button (should trigger error)
casper.click(«button#signUp»);
// Take a screenshot of the UI component
phantomcss.screenshot(«#signUpForm», «sign up form error»);
// Fill in form by name attributes & submit
casper.fill(«#signUpForm», {
name: «Alicia Sedlock»,
email: «[email protected]»
}, true);
// Take a second screenshot of success state
phantomcss.screenshot(«#signUpForm», «sign up form success»);
});

Вступ в тестування front end коду

Цей фреймворк візуального регресу ілюструє дерева рішень у додатку, збільшуючи складність тих дерев, які поки що не розробляються.

На відміну від юніт тестів і приймального тестування, візуальний регрес мало корисний при розробці чогось нового. У фазі активної розробки ваш UI буде швидко зазнавати значні зміни, тому збережіть ці тести до моменту, коли інтерфейс прийде до візуально закінченому станом. Тому тести на візуальний регрес потрібно писати в останню чергу.

На даний момент безліч інструментів для візуального регресу вимагають ручного налаштування. Можливо, вам доведеться запустити зняття скріншотів ще до початку розробки в своїй гілці, або ж вручну оновлювати скріншоти у вихідних умовах при внесенні змін до інтерфейс.

Вся справа в характері розробки – зміни в UI можуть бути і очікуваними, але тести знають тільки «так, тут так» і «ні, це відрізняється». Тим не менш, хоча візуальний регрес і є найболючішою точкою в додатку, цей підхід може заощадити час і зусилля вашій команді, порівняно з постійними фиксами регресій.

4. Тести доступності і продуктивності

Культура і знання front end тестування ростуть, як і наші здібності тестувати різні аспекти екосистеми. Наша технокультура велике значення приділяє доступності і продуктивності, їх інтеграція в тестові сьюти допоможе переконатися, що концепції все ще в пріоритеті.

Якщо у вас проблеми з дотриманням бюджету продуктивності або стандартів доступності, то от вам спосіб тримати ці вимоги на першому місці в головах людей.

Обидві перевірки можна інтегрувати в робочий процес як з допомогою білд інструментів типу Grunt і Gulp, або інтегрувати підлозі-вручну через термінал. Для бюджетів продуктивності є інструмент grunt-perfbudget, що дозволяє проганяти через сайт WebPageTest автоматично через задану задачу.

Якщо ж ви не використовуєте таск раннеры, ви можете підключити perfbudget як незалежний NPM модуль і запускати тести вручну.

Як запускати через термінал:

perfbudget —url http://www.aliciability.com —key [WebPageTest API Key] —SpeedIndex 2000-render 400
And likewise, setting up through Grunt:
perfbudget: {
default: {
options: {
url: ‘http://aliciability.com’,
key: ‘WebPageTest API Key’,
budget: {
SpeedIndex: ‘2000’,
render: ‘400’
}
}
}
}
[…]
grunt.registerTask(‘default’, [‘jshint’, ‘perfbudget’]);

Те ж саме можна зробити для тестування доступності. Для Pa11y ви можете запустити команду pa11y в браузері для висновку, так і створити завдання для автоматизації цього кроку. У терміналі:

pa11y aliciability.com
// As a JavaScript command after NPM install
var pa11y = require(‘pa11y’); // require pa11y
var test = pa11y(); // get pa11y ready to set
test.run(‘aliciability.com’, function (error, results) {
// Log our parse your results
});

Більшу частину інструментів можна використовувати відразу після підключення, але в них також можна налаштувати спосіб запуску тестів. Наприклад, можна змусити тести ігнорувати певні WCAG стандарти.

Вступ в тестування front end коду

Багато розробники вже використовують front end тестування у себе в коді, інші ж досі сумніваються у вигоді. Якщо ви думаєте про включення front end тестування в робочий процес, вам слід врахувати наступні моменти:

1. Почніть з відомих больових місць

Якщо ви помічаєте, що в одних і тих же місцях коду постійно вискакують одні і ті ж помилки, то було б непогано подумати, а не чи допоможе тут тестування.

Якщо у вас регресія коду і вже неможливо написати юніт тести, спробуйте написати приймальні тести, щоб вони покривали сценарії високого рівня. Ви отримаєте базові тести, за якими можна експериментувати. Якщо кількість регресій функції знижується після написання тестів, ви можете знайти інших розробників, більш схильних до написання тестів в майбутньому.

2. Зробіть тестування частиною робочого процесу

Щоб розробники говорили тільки правду про написання тестів, потрібно щоб всі відчували відповідальність. Можливо розмови про тести стануть частиною процесу рев’ю коду: запитайте, чому не написані тести, або вкажіть області, де вони б стали в нагоді.

Ведучи відкритий діалог з тестів, ви можете знайти спосіб замотивировть команду писати їх. Використовуйте сервіси безперервної інтеграції для автоматичного прогону тест сьютов dev на гілках – це підвищить прозорість тестів.

Вступ в тестування front end коду

3. Не робіть все відразу

Якщо команда до цього не була знайома з тестуванням, то прийняття всіх методик відразу перевантажить людей. Якщо ви починаєте з нуля, то вам не потрібні всі методи. Наприклад, якщо у вас не так багато клієнтської логіки та інтерфейсу взаємодії, можливо, візуальні регрес покриє більшу частину програми.

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

4. Перегляд і рев’ю

Тестування, як і інший код, що вимагає постійного перегляду для перевірки, що поточна реалізація відображає дійсність. Пам’ятайте, що тест сьют, який ніхто не запускав – це тест сьют, який не існує.

Але якщо ви приділіть час і зусилля стратегії тестування, то час, заощаджений на поправках регресій, можна буде витратити на розробку нових функцій або поліпшення існуючого коду.