Цей матеріал допоможе вам побачити повну картину тестування JavaScript у веб-спільноті станом на 2019.
Останнім часом приємно спостерігати за еволюцією тестування веб-сайтів. Лише декілька років тому воно було повільним, дорогим, важким для реалізації, невизначеним і загалом не дуже приємним для роботи.
Але, «для JavaScript-розробників ще не було часів кращих, ніж тепер», принаймні, якщо вірити The State of JavaScript 2018. Особливо це стосується JavaScript Testing, де показник «загального задоволення» виріс з позначки 3.2 до 3.8 з 5 у порівнянні з минулим роком.
Сьогодні інструменти тестування веб-сайтів швидкі, інформативні, прості в роботі, тому розробка з ними набагато приємніша.
Заглядаючи наперед, можна передбачити появу штучного інтелекту в галузі автоматизованого тестування. Подібні інструменти вже є і вони активно покращують робочий процес та досвід тисяч розробників.
Типи тестів
Дізнатися більше про різні види тестів можна тут, тут і тут.
Ось найбільш важливі типи тестування веб-сайтів:
- Юніт-тестування— тестування окремих блоків (юнітів), таких як функції або класи, шляхом порівняння вихідних даних з очікуваним результатом:
expect(fn(5)).to.be(10)
- Інтеграційне тестування — тестування процесів декількох блоків, разом з їхніми сторонніми ефектами:
const flyDroneButton = document.getElementById('fly-drone-button')
flyDroneButton.click()
assert(isDroneFlyingCommandSent())
//або навіть
drone.checkIfFlyingViaBluetooth()
.then(isFlying => assert(isFlying))
- Функціональне тестування (також відоме як e2e) — тестування поведінки функцій безпосередньо на готовому продукті шляхом контролю браузера чи веб-сайту. Зазвичай такі тести ігнорують внутрішню структуру застосунку та розглядають його як чорну скриньку.
Перейдіть на сторінку "https://localhost:3303"
Введіть "test-user" у полі "#username"
Введіть "test-pass" у полі "#password"
Натисніть на "#login"
Очікуйте перехід на сторінку
https://localhost:3303/dashboard
Очікуйте, що значення "#name" буде "test-name"
Виконання тестів
Тести можна запускати у браузері, створивши HTML-сторінку з підключеними бібліотеками для тестування, а самі тести підключити як js-файли.
Також тести можна запустити у Node.js, просто імпортувавши їх та залежні бібліотеки. jsdom часто використовується у Node.js для імітації середовища браузера за допомогою чистого JavaScript. Тобто ми отримуємо window, document, body, location, cookies, selectors і все, що тільки потрібно для запуску JS у браузері, але рендеринг не справжній. Варто помітити відмінність від headless mode, для якого потрібен справжній браузер. До того ж у headless mode можна робити скріншоти, на відміну від jsdom.
Рекомендовано використовувати поєднання Node.js + jsdom, тому що з таким підходом тести запускаються швидше, ніж у браузері. Перший спосіб з браузером може бути надійнішим, тому що ви використовуєте ті самі програми, що рендерять ваш сайт насправді. Однак jsdom доцільніший, якщо вам важлива простота. Його достатньо у більшості випадків.
Типи інструментів тестування
Інструменти для тестування можна згрупувати за їх функціональними можливостями. Деякі обмежуються однією функціональністю, інші більш універсальні.
Для досягнення максимальної гнучкості зазвичай використовують поєднання декількох інструментів.
- Лаунчери тестів запускають ваші тести у браузері чи Node.js з конфігурацією користувача за допомогою CLI або UI. Такого ж ефекту можна досягнути, відкриваючи браузер вручну (Karma, Jasmine, Jest, TestCafe, Cypress).
- Інструменти, що піклуються про структуру тестування, допоможуть організувати тестові файли (Mocha, Jasmine, Jest, Cucumber, TestCafe, Cypress).
- Assert-функції перевіряють результат тесту на відповідність очікуваному (Chai, Jasmine, Jest, Unexpected, TestCafe, Cypress).
- Інструменти, що генерують і відображають перебіг тесту та його результати(Mocha, Jasmine, Jest, Karma, TestCafe, Cypress).
- Mock, spy та stub для ізоляції певних частин тестів та відстеження їх сторонніх ефектів (Sinon, Jasmine, enzyme, Jest, testdouble).
- Інструменти, що генерують та порівнюють знімки структур компонентів та даних, аби переконатися у застосуванні змін від попередніх запусків (Jest, Ava).
- Інструменти, що генерують звіти про покриття коду, щоб дізнатись, скільки коду покривається вашими тестами (Istanbul, Jest, Blanket).
- Контролери браузера імітують дії користувача для функціональних тестів (Nightwatch, Nightmare, Phantom, Casper, TestCafe, Cypress).
- Інструменти візуальної регресії використовуються для візуального порівняння сайту з попередніми версіями за допомогою методів порівняння зображень (Applitools, Percy, Wraith, WebdriverCSS).
Пояснимо деякі поняття:
Тестові лаунчери отримують список тестів, а також різноманітні конфігурації, необхідні для запуску цих тестів (які браузери запускати, які плагіни babel використовувати, як форматувати вивід тощо).
# Встановлення Karma:
npm install karma --save-dev
# Встановлення необхідних плагінів
npm install karma-jasmine jasmine-core karma-chrome-launcher karma-firefox-launcher --save-dev
# Запуск
npx karma start karma.conf.js --log-level debug --single-run
module.exports = function(config) {
config.set({
basePath: '../..',
frameworks: ['jasmine'],
autoWatch: true,
browsers: ['Firefox', 'Chrome'],
files: [
// простий шаблон для завантаження необхідних тестових файлів
// еквівалентний такому: {pattern: 'test/unit/*.spec.js', watched: true, served: true, included: true}
'test/unit/*.spec.js'
],
//...
})
}
Структура тестів належить до організаційних аспектів. Зазвичай тести організовані в структуру BDD (розробку, засновану на поведінці). Часто це має такий вигляд:
describe('calculator', function() {
// опис модуля з вкладеною функцією "describe"
describe('add', function() {
// визначення очікуваної поведінки
it('should add 2 numbers', function() {
//використання assertion функцій для тестування очікуваної поведінки
...
})
})
})
Assertion-функції використовують, аби переконатися, що протестована змінна має очікуване значення. Вони мають такий вигляд (перші два стилі найбільш поширені):
// застосування expect в Chai
expect(foo).to.be.a('string')
expect(foo).to.equal('bar')
// застосування expect в Jasmine
expect(foo).toBeString()
expect(foo).toEqual('bar')
// застосування assert в Chai
assert.typeOf(foo, 'string')
assert.equal(foo, 'bar')
// застосування expect в Unexpected
expect(foo, 'to be a', 'string')
expect(foo, 'to be', 'bar')
Дізнатися більше про assertions у Jasmine та Jest можна за посиланням.
Spies дають нам інформацію про функції. Наприклад, скільки разів їх викликали, в яких випадках та в який спосіб?
Spies використовуються в інтеграційних тестах, щоб перевірити сторонні ефекти процесів. Наприклад, скільки разів функція підрахунку викликалась під час певного процесу?
Зверніть увагу, як ми викликаємо father.execute()
та підраховуємо, скільки разів виконувалось father.child
.
class Child {
...
execute() { ... }
...
}
class Father {
constructor() {
this.child = new Child()
}
...
execute() {
...
this.child.execute()
...
this.child.execute()
...
}
...
}
it('should call child execute twice when father executes', () => {
const father = new Father()
// cтежимо за object.method
const childSpy = sinon.spy(father.child, 'execute')
// викликаємо метод з аргументом "3"
father.execute()
// переконуємось, що child.execute виконався двічі
assert(childSpy.calledTwice)
})
Stubbing або dubbing замінює певні методи наявних модулів користувацькими функціями для забезпечення очікуваної поведінки під час тесту.
Щоб переконатися, що user.isValid(
) завжди повертатиме true
під час тесту, де перевіряються різні компоненти, можна використати:
// Sinon
sinon.stub(user, 'isValid').returns(true)
// робота stubs у Jasmine
spyOn(user, 'isValid').andReturns(true)
// Тестування someFn з параметром user де user.isValid() повертає true
assert(someFn(user))
Mocks або Fakes слугують для імітації певних модулів або поведінки для тестування різних частин процесів.
Sinon, наприклад, може зімітувати сервер, щоб офлайн перевірити очікувані відповіді.
it('returns an object containing all users', done => {
// створення та конфігурація імітованого сервера
const server = sinon.createFakeServer()
server.respondWith('GET', '/users', [
200,
{ 'Content-Type': 'application/json' },
'[{ "id": 1, "name": "Gwen" },{ "id": 2, "name": "John" }]'
])
// виклик процесів, що містять запити
Users.all()
.done(collection => {
const expectedCollection = [
{ id: 1, name: 'Gwen' },
{ id: 2, name: 'John' }
]
expect(collection.toJSON()).to.eql(expectedCollection)
done()
})
// відповідь на запит
server.respond()
// видалення імітованого сервера
server.restore()
})
Тестування знімками полягає у порівнянні структур даних з очікуваним результатом.
Приклад з офіційної документації Jest ілюструє тестування знімками певного компонента Link
.
it('renders correctly', () => {
// створення екземпляру компонента Link з атрибутом page та дочірнім текстом
const linkInstance = (
<Link page="http://www.facebook.com">Facebook</Link>
)
// створення знімку даних компоненту
const tree = renderer.create(linkInstance).toJSON()
// порівняння даних з останнім знімком
expect(tree).toMatchSnapshot()
})
Насправді, для збереження знімку компонента не потрібен його рендеринг. Достатньо збереження його внутрішніх даних в окремому файлі, на зразок такого:
exports[`renders correctly 1`] = `
<a
className="normal"
href="http://www.facebook.com"
onMouseEnter={[Function]}
onMouseLeave={[Function]}
>
Facebook
</a>
`;
Коли тест запускається, а новий знімок відрізняється від останнього, розробнику буде запропоновано підтвердити, що зміни здійснено направлено.
Зверніть увагу: знімки зазвичай створюються для порівняння даних представлення компонента, але вони також можуть використовуватись для інших типів даних, на зразок redux store або внутрішньої структури різних модулів застосунку.
Браузери можна контролювати за допомогою драйверів, що встановлюються поверх них і здійснюють контроль різними способами. Так працює selenium.
Node.js <=> WebDriver <=> FF/Chrome/IE/Safari drivers <=> browser
Інший спосіб — додати JS-код, який має доступ до повного середовища застосунку: DOM, мережі, cookies тощо. Таким чином, отримуємо дії, що імітують поведінку користувача. Наприклад:
document.getElementByID('someButton').dispatchEvent(clickEvent).
Node.js <=> FF/Chrome/IE/Safari injected script <=> Simulated events
Збираємо все докупи
Почніть з вибору структури тестування та синтаксису, який вам подобається, бібліотеки assert-функцій та вирішіть, як ви хочете запускати тести.
Деякі фреймворки, на зразок Jest, Jasmine, TestCafe та Cypress, мають увесь перелічений функціонал з коробки. Інші ж пропонують лише частковий функціонал, який можна доповнити комбінацією декількох бібліотек (наприклад, mocha + chai + sinon).
Найкраще створювати два різних процеси. Один для запуску модульних та інтеграційних тестів, а інший — для функціональних тестів. Усе тому, що функціональні тести зазвичай потребують більше часу, особливо для запуску набору тестів в декількох різних браузерах.
Подумайте, коли запускати той чи інший тип тесту. Наприклад: модульний+інтеграційний для кожної зміни, функціональний — лише перед комітами.
Модульні тести
Такі тести покривають усі невеликі чисті модулі застосунку: utils, сервіси і хелпери. Додайте у ці модулі просту та демонстративну інформацію на вхід та оцініть правильність вихідної інформації, використовуючи assert-функції. Також пам'ятайте про звіти тестового покриття, щоб оцінити які модулі були покриті тестами.
Модульні тести – одна з причин використовувати функціональне програмування та чисті функції якомога більше.
Чим чистіший ваш застосунок, тим легше його тестувати.
Інтеграційні тести
Раніше тести були зосереджені на тестуванні модулів і все завершувалось застосунком, в якому окремі невеликі частини працювали, але при їх об'єднанні все провалювалось.
Інтеграційні тести, з іншого боку, відстежують випадки, коли провівся рефакторинг і модуль пройшов тести, але процес, що залежить від нього, провалився.
Важливо також пам'ятати, що в реальних умовах, через недосконале проектування і широке використання чорних скриньок, не всі модулі є чистими і піддаються тестуванню — деякі з них можуть бути протестовані тільки як частина більшого процесу.
Інтеграційні тести повинні покривати важливі процеси, що охоплюють декілька модулів. Іноді вони поширюються на процеси декількох класів, а іноді на тестування взаємодії фронтенд-бекенд.
На відміну від модульних тестів, маємо перевагу у використанні механізму spies для перевірки очікуваних сторонніх ефектів (замість assert-функцій). Інша перевага — у механізмі stubs для імітації та модифікації частин процесу, які не покриваються поточним тестом.
На противагу юніт-тестам, браузер чи подібне середовище (jsdom) може вимагати доступу до window
.
Тестування компонента знімками належить до цієї ж категорії. Вони перевіряють, як процеси впливають на обрані компоненти, без фактичного їх рендерингу у браузері.
Функціональні тести
Іноді швидкого модульного та ефективного інтеграційного тестування недостатньо.
Функціональні тести контролюють браузер та імітують поведінку користувача (кліки, ввід, скролінг тощо), аби упевнитись, що усі сценарії працюють з погляду користувача.
Варто зазначити, що багато сервісів дають вам інструменти та браузери для запуску цих тестів. Більше інформації за посиланням.
Інструменти тестування візуальної регресії також призначені для перевірки роботи представлень вашого застосунку шляхом порівняння скріншотів. Такі скріншоти зазвичай є частиною функціональних тестів або ж отримуються завдяки виконанню окремої сесії автоматизації браузера.
Перелік найбільш відомих інструментів тестування
Існує безліч чудових інструментів. Тут перелічені не всі, а лише найкраще підтримувані та найбільш зручні:
jsdom
jsdom — JavaScript-реалізація стандартів WHATWG DOM та HTML. Іншими словами: jsdom імітує середовище браузера за допомогою чистого JS.
З цим інструментом тести дійсно швидкі. Недолік jsdom у тому, що не все можна імітувати за межами реального браузера (наприклад, не можна зробити скріншот), тому можливості вашого тесту будуть обмежені.
Варто зазначити, що спільнота JS досить швидко покращує jsdom і остання версія дуже подібна на реальний браузер.
Electron
Фреймворк дає можливість писати кросплатформені десктопні застосунки, використовуючи JavaScript, HTML і CSS. Також підтримує headless-режим.
Electron може похвалитися великою спільнотою і кількістю відомих застосунків, створених на його основі: Atom, Slack, Skype, GitHub Desktop та багато інших.
Інструменти тестування, на зразок Cypress.io використовують Electron для запуску тестів з максимальним контролем над браузером.
Istanbul
Istanbul допоможе вам з'ясувати, яка кількість коду покрита юніт-тестами. Він може звітувати про вираз, рядок, функцію та сукупність змін у процентах так, щоб ви краще розуміли, як йдуть справи.
Karma
Karma організовує сервер для тестування зі спеціальною веб-сторінкою для запуску тестів. Така сторінка може відкриватися у багатьох браузерах і браузерних середовищах, на зразок jsdom.
Chai
Chai — найбільш популярна бібліотека assert-функцій. Має багато плагінів та розширень.
Unexpected
Unexpected — бібліотека assert-функцій, синтаксис якої трохи відрізняється від Chai. Вона також підтримує розширення, тому assert-функції можуть бути складнішими. Наприклад, можна використовувати плагін unexpected-react, про який детальніше за посиланням.
Sinon.JS
Sinon має дуже потужні автономні тестові spies, stubs та mocks для JavaScript і працює з будь-якою платформою модульного тестування.
testdouble.js
testdouble — менш популярна бібліотека, подібна до Sinon, але має відмінності у дизайні, філософії та фічах, корисних у багатьох випадках. Дізнатися більше можна тут, тут і тут.
Wallaby
Ще один інструмент, вартий уваги. Він не безкоштовний, але багато користувачів рекомендують його придбати. Запускається на вашій IDE (підтримує усі основні) та запускає тести, причетні до змін вашого коду, і вказує, якщо щось не так з вашим кодом, у режимі реального часу.
Cucumber
Cucumber допомагає у написанні тестів у BDD (розробка через поведінку) шляхом їх поділу між файлами критеріїв прийняття з використанням синтаксису Gherkin і відповідними тестами.
Тести можуть бути написані багатьма мовами (зокрема JS), які підтримуються фреймворком:
Функція: Читач може поділитися статтею у соціальних мережах
Як читач
Я хочу поділитися статтями
Щоб мої друзі дізналися яка стаття мені сподобалась
Сценарій: Стаття була відкрита
Враховуючи, що я всередині статті
Коли я ділюся статтею
Вона повинна змінити свій стан на "shared"
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.
Перелік найпопулярніших інструментів та їх характеристик:
Jest
Jest — фреймворк для тестування, створений та підтримуваний Facebook. У 2017 році він здобув статус найпопулярнішої бібліотеки року (за результатами State of Javascript 2017 vs 2018).
В його основі лежить Jasmine. З часом Facebook замінив більшу частину функціональності фреймворку і додав безліч нових можливостей.
Якщо вірити великій кількості схвальних статей та постів, користувачі дійсно вражені швидкістю та зручністю Jest.
- Продуктивність: Jest вважається швидким рішенням для великих проектів з безліччю тестових файлів. Усе завдяки розумному механізму паралельного тестування. Детальніше тут, тут і тут.
- UI: чистий та зручний.
- Готовність до роботи: містить assert-функції, spies та mocks, що еквівалентно функціоналу бібліотек, на зразок Sinon. Але ви досі можете використовувати бібліотеки, якщо вам потрібен якийсь особливий функціонал.
- Глобальні змінні: як і Jasmine, він за замовчування створює globals у тестах. Та є ризик негативних наслідків: ваші тести можуть бути менш гнучкими та контрольованими.
// "describe" одразу в глобальній області видимості
// таким чином наступні рядки більше не потрібні:
// import { describe } from 'jest'
// import { describe } from 'jasmine'
describe('calculator', function() {
...
})
- Тестування знімками: jest-snapshot розроблений та підтримується Facebook, хоча він може бути використаний майже у будь-якому іншому фреймворку як частина інтеграції або за допомогою правильних плагінів.
-
Покращена імітація модулів: Jest дозволяє з легкістю імітувати великі модулі для покращення швидкості тестів. Наприклад, можна зімітувати сервіс для виклику
resolve
для промісів, замість реального мережевого запиту. - Покриття коду: є вбудований потужний і швидкий інструмент покриття коду, в основі якого Istanbul.
- Надійність: хоч бібліотека відносно молода, протягом 2017 та 2018 років вона підтвердила свою надійність. Зараз підтримується усіма основними IDE та інструментами.
- Розробка: Jest оновлює лише потрібні файли, тому тести працюють дуже швидко у режимі перегляду.
jasmine
Jasmine — фреймворк для тестування, на якому базується Jest. Чому ви віддасте перевагу Jasmine, а не Jest? Про це вже є безліч статей та обговорень на форумах.
Angular рекомендує використовувати саме Jasmine, однак Jest також чудово підходить для запуску Angular тестів.
- Готовність до роботи: містить усе необхідне для початку тестування.
- Глобальні змінні: доступні усі важливі фічі тестування у глобальному масштабі.
- Спільнота: діє з 2009-го року, за цей час накопичилось багато статей, рекомендацій та інструментів.
- Angular: має широку підтримку усіх версій Angular, тому рекомендується їх офіційною документацією.
mocha
Mocha — найбільш поширена бібліотека. На відміну від Jasmine, використовується зі сторонніми інструментами для assertions, mocking та spying (зазвичай це Sinon та Chai).
Встановити Mocha трохи складніше через поділ на бібліотеки, натомість у ній є простір для розширень.
Наприклад, якщо вам потрібна особлива логіка асертів, ви можете замінити Chai власною бібліотекою. Те ж саме можна зробити і з Jasmine, однак у Mocha все чистіше та очевидніше.
- Спільнота: багато плагінів та розширень для тестування особливих сценаріїв.
- Розширюваність: розширювана настільки, що плагіни та бібліотеки розробляються спеціально для Mocha.
- Глобальні змінні: створює за замовчуванням, однак не працює з assertions, spies та mocks, як Jasmine. Багатьох дивує така непослідовність.
AVA
Ava — мінімалістична бібліотека для запуску паралельних тестів.
- Готовність до роботи: містить все необхідне для початку тестування (окрім spying та dubbing, які можна з легкістю додати). Запускається у Node.js; використовує такий синтаксис для тестових структур та асертів:
import test from 'ava'
test('arrays are equal', t => {
t.deepEqual([1, 2], [1, 2])
})
- Глобальні змінні: не створює глобальних змінних, тому можна повністю контролювати тести.
- Простота: проста структура та assert-методи без складного API, натомість з просунутими фічами.
- Розробка: оновлює лише потрібні файли, тому тести запускаються швидко у режимі перегляду.
- Швидкість: запускає тести паралельно як окремі процеси Node.js.
- Тестування знімками: підтримується як частина фреймворку.
tape
Tape — найпростіша бібліотека з перелічених. Це просто JS-файл, який ви запускаєте у Node з дуже простим API.
- Простота: мінімалістична структура та асерти без складного API.
- Глобальні змінні: не створює, тому ви маєте більше контролю над власними тестами.
-
Не поширює стан між тестами: Tape перешкоджає використанню таких функцій, як
beforeEach
, для забезпечення модульності тестування і максимального контролю над перебігом тестів. - Не потрібен CLI : Tape запуститься усюди, де може запуститись JS.
Інструменти для функціонального тестування
Як вже зазначалось, тут і тут ви знайдете чудові статті про запуск тестів на різних пристроях і браузерах.
Інструменти для функціонального тестування сильно відрізняються один від одного у способі реалізації, філософії та API. Тому дуже радимо витратити час, щоб зрозуміти різницю та протестувати все на власному продукті.
Якщо ви хочете чимшвидше почати: з простим налаштуванням, крос-браузерністю та максимально повним функціоналом, зупиніться на TestCafe.
Якщо для вас важливий зручний UI, чиста документація, класні фічі та широкий функціонал, вам знадобиться Cypress.io.
Якщо віддаєте перевагу добре перевіреним інструментами, розпочніть з Nightwatch.js.
Якщо вам потрібен не просто перевірений часом інструмент, а ще й максимальна підтримка спільноти та гнучкість, вам допоможе WebdriverIO.
Якщо вам потрібне надійне рішення, що добре підтримується в Angular, — це Protractor.
selenium
Selenium та залежні інструменти домінують на ринку функціонального тестування вже багато років. Він не був створений спеціально для тестування, тому може контролювати браузер для багатьох цілей, надаючи драйвер, що керує браузерами за допомогою надбудов і розширень.
Node.js <=> WebDriver <=> FF/Chrome/IE/Safari drivers <=> browser
До WebDriver можна звернутися у багато способів, за допомогою різних мов програмування і деяких інструментів, навіть без написання коду.
Ви можете імпортувати WebDriver у ваш фреймворк і писати тести з його використанням:
describe('login form', () => {
before(() => {
return driver.navigate().to('https://web.archive.org/web/20230321175407/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.
Оглянемо деякі бібліотеки Selenium:
Protractor
Protractor — бібліотека, що огортає Selenium і забезпечує покращений синтаксис та спеціальні вбудовані хуки для Angular.
- Angular: Protractor має спеціальні хуки для фреймворку, однак чудово може використовуватись також і з будь-яким іншим фреймворком. Офіційна документація Angular рекомендує.
- Звіт про помилки: зручна фіча.
- Підтримка: доступна підтримка TypeScript, а сама бібліотека керується і підтримується величезною командою Angular.
WebdriverIO
WebdriverIO має власну реалізацію WebDriver від Selenium.
- Синтаксис: простий та читабельний.
- Гнучкість: проста, гнучка та розширювана бібліотека.
- Спільнота: постійна підтримка та ентузіазм розробників.
Nightwatch
Nightwatch має власну реалізацію WebDriver від Selenium. Передбачає фреймворк для тестування з сервером, асертами та додатковими інструментами.
- Фреймворки: може також використовуватись у поєднанні з іншими фреймворками, але особливо корисний, якщо ви хочете запустити функціональні тести окремо від вашого фреймворку.
- Синтаксис: легкий та дуже читабельний.
- Підтримка: немає підтримки TypeScript. Бібліотека здається менш підтримуваною у порівнянні з іншими.
Appium
Apium має подібний до Selenium API для тестування веб-сайтів на мобільних пристроях, використовує такі інструменти:
- iOS 9.3+: Apple's XCUITest
- Before iOS 9.3: Apple's UIAutomation Android 4.2+: Google's UiAutomator/UiAutomator2
- Android 2.3+: Google's Instrumentation (підтримка Itrumentation за допомогою окремого проекту – Selendroid).
- Windows Phone: Microsoft's WinAppDriver.
Тому, якщо вам потрібен Selenium або інструменти на його основі для тесту на мобільних пристроях, зупиніться на Apium.
TestCafe
TestCafe — чудова альтернатива інструментам від Selenium. Він був переписаний та перетворений на open-source наприкінці 2016.
TestCafe має також платну версію, яка пропонує інструменти для тестування, що не потребують написання коду. Вона застаріла, а зміну їй прийшов TestCafe Studio, який наразі безкоштовний, але стане комерційним продуктом з офіційним релізом за декілька місяців.
TestCafe вбудовується у веб-сайт як JavaScript, замість того, щоб котролювати безпосередньо браузер, як це робить Selenium. Такий підхід дозволяє запускати тести на будь-якому браузері, а також мобільних пристроях та мати повний контроль над виконанням скриптів.
-
Швидкий у встановленні: виконайте
npm install
та запускайте тести на будь-якому браузері. - Крос-браузерність та підтримка різних пристроїв: може використовуватись із SauceLabs або BrowserStack, які забезпечують пристрої для ваших тестів. Також підтримується запуск тестів у Headless Chrome та Headless Firefox.
- Паралельне тестування: TestCafe може запускати ваші тести у декількох браузерах одразу. Такий підхід може значно зменшити час, витрачений вами на тестування.
- Зручний звіт про помилки.
- Власна екосистема:TestCafe використовує власну структуру тестів. Такий підхід може здатися більш зручним, особливо тому що тести UI зазвичай запускаються окремо від інших тестів. Але не всім це до вподоби.
Cypress
Cypress — головний конкурент TestCafe. Вони роблять приблизно те саме: вбудовують тести у веб-сайт, але у більш сучасний, гнучкий і зручний спосіб.
Різниця між ними у тому, що Cypress запускається у браузері та контролює ваші тести, а TestCafe запускається у Node.js і контролює тести через серіалізацію взаємодії із вбудованими у браузер скриптами.
Бібліотека відносно нова (публічна бета-версія випущена у жовтні 2017), але вже має багато прихильників.
- Паралельне тестування було представлено у версії 3.10.
- Документація: інформативна та зрозуміла.
- Підтримує доступ до всіх змінних вашого застосунку без серіалізації (TestCafe, з іншого боку перетворює об'єкти у JSON, надсилає їх Node.js як текст, а потім парсить назад в об'єкти).
- Дуже зручні інструменти для налагодження та запуску: із логуванням тестових процесів не буде ніяких труднощів.
- Немає крос-браузерної підтримки: поки є лише підтримка Chrome, але не headless, натомість є підтримка headless-режиму в Electron. Проте на момент написання статті проходить робота щодо додавання цього функціоналу.
- Бракує деяких юзкейсів, але вони постійно розробляються, як от HTML5 drag-n-drop
- Використання Mocha як основи тестової структури досить поширене та дозволяє вашим функціональним тестам мати подібну структуру з іншими тестами.
describe('My First Cypress Test', function() {
it("Gets, types and asserts", function() {
cy.visit('https://web.archive.org/web/20230321175407/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 або Headless Chrome.
Headless Chrome — звичайна версія Chrome v59+, яка запускається з прапором --headless
. Коли Chrome запускається в такому режимі, він надає API для керування ним. Саме для цього Google передбачив Puppeteer.
Варто зазначити, що Firefox також випустив haedless-версію наприкінці 2017.
Багато з перелічених інструментів для тестування також використовують Headless Chrome та Firefox (наприклад, TestCafe, Karma, Cypress).
- Puppeteer відносно новий, але має велику спільноту, яка розробляє супутні інструменти.
- Оскільки бібліотека нативна та використовує останній рушій Chrome, вона надзвичайно швидка.
- Суттєвий недолік Headless Chrome (а отже і Puppeteer) у тому, що він не підтримує розширення (як Flash) і навряд найближчим часом буде.
PhantomJS
Phantom реалізовує рушій chromium для створення контрольованого headles-браузера, подібного до Chrome. Цей інструмент був чудовим рішенням для запуску headless-режиму, поки Google не представив Puppeter.
Проект більше не підтримується, а репозиторій було архівовано.
Nightmare
Nightmare — бібліотека для функціонального тестування, яка пропонує простий синтаксис.
Вона використовує Electron, який контролює поведінку браузера за допомогою Chromium.
Вже також не підтримується. Можливо, тому що Puppeteer пропонує ті самі фічі з коробки.
CodeceptJS
Подібно до CucumberJS, що згадувався вище, Codecept пропонує іншу абстракцію над різними API бібліотек для того, щоб ваш підхід до тестів ґрунтувався на поведінці користувача.
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.
Тестування візуальної регресії
Інструменти тестування візуальної регресії мають приблизно такі складники:
- Методи та інтеграції для автоматизованого запуску тестів як частини функціонального тестування у браузері.
- Створення розумних скріншотів у форматі зображень та знімків DOM.
- Методи порівняння зображень та DOM для встановлення відмінностей, навіть за допомогою штучного інтелекту.
- Схвалення UI користувачами для організації зручного інтерфейсу.
На ринку є велика кількість інструментів цього типу тестування, але вони ще не зовсім досконалі.
Платні інструменти у категорії тестування візуальної регресії набагато кращі за безкоштовні.
Applitools
- Легко встановлюється.
- Використовує штучний інтелект для порівняння та оцінки користувачами різниці, а також зводить кількість помилкових збігів до мінімуму.
- Зручно інтегрується із вже описаними інструментами.
- Має безкоштовні та платні версії, а також спеціальні плани для стартапів та некомерційних організацій.
Percy
- Простий у налаштуванні.
- Використовує розумні методи порівняння.
- Зручне користувацьке порівняння.
- Зручна інтеграція з інструментами.
- Є безкоштовні та гнучкі платні версії.
Happo
Happo — платний інструмент візуального регресійного тестування. Він підключається до CI (безперервної інтеграції) для порівняння вигляду компонентів інтерфейсу до і після зміни.
Скріншоти можна зробити у різних браузерах та для різних розмірів екрану, щоб забезпечити крос-браузерність і адаптивність вашого застосунку.
Платний, але є безкоштовний план для проектів з відкритим сирцевим кодом.
Gemini
Утиліта з відкритим кодом від «Яндексу».
Використовує LooksSame (також від «Яндексу»), який може використовуватись окремо з тією ж метою.
Значно простіший і обмеженіший, ніж платні інструменти, але його вистачить для не дуже складних сайтів.
BackstopJS
Утиліта з відкритим сирцевим кодом для запуску на Chrome Headless. Підтримує Puppeteer та CI (безперервну інтеграцію).
AyeSpy
Бібліотека з відкритим сирцевим кодом, створена командою Times Tooling з News UK.
Використовує selenium docker для створення тестів візуальної регресії у Chrome / Firefox.
reg-suit
Бібліотека з відкритим сирцевим кодом, що порівнює зображення, генерує звіти та зберігає все у хмарі. Дуже зручна, якщо ви хочете додати тести візуальної регресії до наявних функціональних тестів. Просто додає кроки зі створення скріншотів до чинної логіки та порівнює отримані знімки.
Differencify
Ще один інструмент для Chrome Headless. Використовує Puppeteer зі зручною інтеграцією з Jest snapshots. Може запускатися у docker та генерувати зручні звіти.
Інструменти для функціонального тестування без написання коду
testim
Відкриває ваш застосунок в окремому вікні та використовує розширення браузера для запису вашої взаємодії із застосунком як тестового сценарію.
Використовує машинне навчання для запису і перевірки тестових сценаріїв. Крос-браузерний, чудово інтегрований з багатьма CI та засобами взаємодії.
Має безкоштовну та гнучку платну версії.
Screener
Дає можливість записувати тести, використовуючи розширення chrome, організовує докладне звітування. Платформа також передбачає інтеграцію з різними CI, а також з BrowserStack та Sauce Labs.
Є тільки платна версія.
Ще немає коментарів