Автоматизація тестування: принципи, помилки та власний досвід
Усім привіт, мене звати Анна Хрестян, я працюю на позиції General Quality Assurance Engineer у компанії Apriorit. У цій статті розкажу про правила й принципи, що допомагають ефективно впроваджувати автоматизацію в тестуванні, а також розгляну основні інструменти для цього.
Почнемо з бази: автоматизація тестування — це використання спеціальних інструментів для виконання набору тестів замість ручного запуску. Вона дозволяє прискорити випуск релізів, зекономити час на ручній регресії, а також збільшити покриття кейсів.
Проте важливо пам’ятати, що автоматизувати варто не все. Давайте розбиратися разом.
Автоматизація: користь і сенс
Перш ніж говорити про принципи, варто розібратися, яку саме користь приносить автоматизація тестування та коли вона дійсно виправдана.
Що дає автоматизація:
• економія ресурсів на ручне тестування в майбутньому;
• масштабованість;
• прискорення регресійного тестування;
• підвищення якості продукту завдяки широкому покриттю автотестами;
• стабільність виконання завдяки однаковому результату під час кожного запуску;
• зниження ризику випустити зламаний продукт, оскільки кожна збірка перевіряється автоматично.
Коли без автоматизації не обійтися:
- є потреба в тестуванні в різних середовищах (тестове, стейджинг), різних браузерах, різних операційних системах;
- застосунок із великим обсягом функціоналу (регресія може займати занадто багато часу);
- застосунок із тривалим життєвим циклом (автоматизація має окупитися: якщо проєкт розрахований лише на 2 місяці, то автоматизувати тести немає сенсу. Але якщо потрібно знову й знову проводити регресійне тестування, тоді автоматизація має сенс);
- застосунок, який активно розвивається: постійна імплементація нових фіч потребує частого проведення регресійного тестування, тому автоматизація є доцільною;
- впровадження CI/CD;
- високі вимоги до стабільності та якості продукту (якщо ми говоримо про галузі: медицина, фінанси, телеком — навіть низькопріоритетний баг може призвести до серйозних наслідків. Автотести допомагають гарантувати стабільність роботи застосунку);
- складні рішення з інтеграцією мікросервісів і сторонніх платформ (якщо продукт взаємодіє із зовнішніми системами, наприклад через інтеграції з платіжними системами Visa/Mastercard. У такому випадку постійна ручна перевірка стає занадто тривалою, а автотести дозволяють перевіряти тест-кейси взаємодії застосунку з іншими системами).
Принципи ефективної автоматизації
Спираючись на власний досвід, я можу виділити кілька ключових принципів, які допомагають зробити автоматизацію ефективною.
Фокус. Автоматизація не замінює повністю ручне тестування. Вона найбільш ефективна для критичних сценаріїв, що часто повторюються й мають чіткий очікуваний результат.
Натомість нетипові, разові чи низькопріоритетні перевірки краще виконувати вручну, так економляться ресурси й зберігається гнучкість процесу.
Приклад № 1. З моєї практики, всі тести, які належали до smoke-секції, були автоматизовані, щоб перевіряти загальний стан застосунку та доступність сервісів. Якщо ж потрібно було перевірити нетипові сценарії, вони не підлягали автоматизації. Варто чітко відділяти, коли автоматизація потрібна, а коли ні, адже це витрати ресурсів.
Приклад № 2. На нашому проєкті стандартні права доступу користувачів перевіряються автотестами. Це дозволяє зекономити час на ручному тестуванні. Водночас перевірка з особливими наборами прав доступу проводиться вручну, оскільки це не типовий кейс.
Стабільність: автотести мають бути стабільними. Ми повинні покладатися на якість написаних автотестів: вони повинні працювати стабільно. «Флакі» тести не дають жодної користі, а навпаки витрачають ресурси на аналіз причин невиконання.
Приклад: з моєї практики, нестабільність тестів могла бути спричинена різними чинниками. Проблеми середовища, некоректний селектор елемента, зміни на сторінці тощо. Важливо провести аналіз і визначити, який саме селектор доцільно використовувати для пошуку елемента, а також перевірити стабільність середовища. Щоб остаточно переконатися в стабільності тесту, його потрібно прогнати декілька разів.
Надійність: використання CI для гарантії правильності виконання та надійності автотестів. Якщо інтегрувати тести в CI, вони виконуватимуться автоматично під час кожного білду чи релізу. Це дає можливість наочно бачити кількість стабільних і нестабільних тестів у звітах. Виходячи зі статистики, можна оцінити рівень стабільності всієї системи тестів.
Приклад: на проєкті ми інтегрували автотести в CI, щоб виконувати їх на різних версіях продукту. Це дозволяє швидко локалізувати баги, адже можна порівняти, на яких білдах тести проходять успішно, а на яких — падають. Tакий підхід робить процес тестування прозорим.
Актуальність і підтримка: зміни в продукті повинні відображатися й у тестах. Якщо автотести не оновлювати, вони швидко втрачають цінність.
Приклад: на проєкті вже було близько 20% покриття пріоритетних кейсів автоматизацією, і моїм завданням було далі розвивати цей напрям. Запускаючи існуючі тести, я помітила, що частина з них фейлилася через зміни в UI. Це показало, як важливо підтримувати автотести в актуальному стані: якщо вони швидко оновлюються разом із продуктом, їх можна вважати еталоном того, як саме має працювати система. На відміну від статей у Confluence, які часто не оновлюються й можуть втрачати актуальність, автотести залишаються джерелом достовірної інформації про продукт.
Зрозумілість: архітектура тестів повинна бути простою та зрозумілою. Код автотестів — це також програмний код, і він має бути структурованим і читабельним.
Говорячи про архітектуру автотестів, я б хотіла окремо звернути увагу на кілька важливих практик.
- Використання Page Object Model. Це дозволяє винести всю логіку роботи сторінки в окремий клас. Якщо в UI сталися зміни, достатньо змінити їх в одному місці, і вони підтягнуться для інших тестів.
class LoginPage {
elements = {
loginForm: () => cy.get('#form'),
loginButton: () => cy.get('#login'),
loginFieldName: () => cy.get('#loginFieldName'),
loginFieldPassword: () => cy.get('#loginFieldPassword'),
logoutButton: () => cy.get('#logout')
}
checkLoginForm() {
this.elements.loginForm().should('be.visible');
}
checkLogin(username, password) {
this.elements.loginFieldName().type(username);
this.elements.loginFieldPassword().type(password);
this.elements.loginButton().click();
}
}
Я навела приклад Page Object для сторінки логіну. Як видно зі скриншоту, усі наші елементи, що належать до сторінки логіну, будуть знаходитись у межах однієї сторінки, а самі функції викликатимуться безпосередньо в тесті.
- принцип DRY. Важливий принцип, який закликає не дублювати один і той самий код у різних тестах, а створювати функції/методи для повторного використання. Це робить код більш чистим і підтримуваним. Приклад порушення принципу у тесті Cypress:
it('Login with valid user', () => {
cy.visit('/login');
cy.get('#username').type('user1');
cy.get('#password').type('pass1');
cy.get('#login').click();
cy.get('.successful-login').should('be.visible');
});
it('Login with invalid user', () => {
cy.visit('/login');
cy.get('#username').type('notValidUser');
cy.get('#password').type('notValidPass');
cy.get('#login').click();
cy.get('.error').should('be.visible');
});
Тести без дотримання принципу DRY можуть виглядати як у наведеному вище прикладі. У такому випадку ми постійно дублюємо код для різних тестів: замість одного рядка з викликом функції розписуємо весь тест. Ми маємо уникати цього.
Приклад правильної реалізації:
const loginPage = new LoginPage();
it('Valid login', () => {
loginPage.checkLogin('validUser', 'validPassword');
cy.get('.successful-login').should('be.visible');
});
it('Invalid login', () => {
loginPage.checkLogin('invalidUser', 'invalidPassword');
cy.get('.error').should('be.visible');
});
Ми бачимо, що тут принцип DRY зберігається, оскільки повторювані дії логіну винесені в окремий метод, що дозволяє нам уникати дублювання коду в тестах.
Інструменти: що обрати
Щоб обрати інструмент для автоматизації, варто визначити такі пункти:
- що саме ми тестуємо: Web/UI, мобільний застосунок, API, десктоп, перформанс тощо;
- яка мета тестування: Smoke, регресія, кросбраузерність, навантаження тощо;
- де будемо запускати тести: CI, локально, у контейнері тощо;
- ризики та обмеження: бюджет, швидкість, інтеграції, звітність.
Для написання end-to-end тестів у своїй роботі я використовую Cypress (JS), Testim та Robot Framework. Можу виділити сильні й слабкі сторони цих фреймворків.
Cypress
Сучасний фреймворк на JavaScript/TypeScript для e2e-тестування вебзастосунків.
Посилання на офіційну документацію: docs.cypress.io.
Результат виконання тестового набору у Cypress:

Сильні сторони:
- працює прямо в браузері: можна побачити, як виконується тест і на якому етапі він «падає»;
- зручна система логування;
- легкий старт завдяки доступній документації;
- можливість тестувати не лише UI, а й бекенд (API);
- автоматичне очікування (фреймворк сам чекає, поки елемент стане видимим).
Слабкі сторони:
- обмежена кросбраузерність: спочатку Cypress підтримував лише Chromium-браузери, зараз додали Firefox і WebKit (движок Safari), але не всі функції працюють стабільно.
- не повноцінний API-фреймворк. Cypress може робити API-запити, перевіряти статус-коди та відповіді, але це радше допоміжна можливість. Немає зручних data-driven сценаріїв, складно перевіряти великі чи вкладені JSON-відповіді.
Підсумок: Cypress доцільно використовувати, якщо потрібні стабільні й швидкі end-to-end тести у Chrome/Edge, але кросбраузерність і підтримка API в ньому обмежені.
TestIM
Це інструмент автоматизації тестування, що не потребує написання коду. У мене була можливість почати перехід з ручного тестування на автоматизацію саме з цього фреймворку.
Він чудово підходить для новачків, оскільки тести будуються шляхом запису дій користувача. Посилання на офіційну документацію: www.testim.io.
Інтерфейс фреймворку:

Сильні сторони:
- створення тестів через рекордер (дії записуються прямо у браузері);
- низький поріг входу: новачкам легко навчитись користуватись фреймворком;
- можливість створювати автотести без написання коду;
- можливість писати власні функції на JS/TS.
Слабкі сторони:
- створює не оптимальні локатори для елементів: якщо елемент змінився або перекритий іншим, Testim не зможе його знайти й тест «завалиться»;
- система редагування уже створених локаторів працює складно та не гнучко;
- обмежена безкоштовна версія;
- складності з тестуванням бекенду.
Підсумок: Testim — чудовий фреймворк для новачків, а також для UI, у якому не буде регулярних змін. Якщо ж UI нестабільний, краще обрати Cypress.
Robot Framework
Open-source фреймворк для автоматизованого тестування, написаний на Python. Основна ідея: використання зрозумілих для людей слів та фраз в автотестах, а не «чистого» коду. Також непоганий вибір для початку роботи з автоматизацією. Посилання на офіційну документацію: robotframework.org.
Результат виконання тестового набору у Robot Framework:

Сильні сторони:
- можливість тестувати різні типи застосунків: веб, десктоп, мобільні та API, завдяки підтримці багатьох бібліотек;
- структурована документація (багато ключових слів уже доступні й не потребують створення нових).
Слабкі сторони:
- тести працюють повільніше, бо виконуються через WebDriver, а не напряму в браузері (як, наприклад, в Cypress);
- складніше налагоджувати тести (лише лог-файли, без візуального інтерфейсу).
Підсумок: Robot Framework не завжди підходить для великих або складних UI-проєктів, оскільки масштабування тестів і підтримка структури можуть бути складними. Але якщо продукт уже стабільний і потрібні читабельні та надійні тести, цей фреймворк може стати вірним рішенням.
Слабкі місця автоматизації
Попри очевидні переваги, автоматизація має свої слабкі місця.
Недоліки та обмеження автоматизації:
- Великі витрати на початкових етапах. Автоматизація окупається лише тоді, коли тести запускаються багато разів. Потрібні час і ресурси, щоб написати тести, налаштувати середовище, CI/CD та інфраструктуру. Спочатку автоматизація дорожча й повільніша, ніж ручне тестування.
- Постійна підтримка автотестів. Тести мають завжди бути в актуальному стані з урахуванням усіх змін в UI. Якщо тести погано структуровані, вони перетворюються на «флакі»-тести.
- Обмежене покриття. Автотести перевіряють лише те, що в них закладено. Вони не можуть повністю замінити ручне тестування, адже не здатні оцінити UX, юзабіліті чи дизайн.
- Потреба у спеціалістах, які мають необхідні навички (бажано, хоча б з базовим знанням програмування): якщо таких спеціалістів немає, то треба витратити ресурси на навчання.
Типові помилки:
- Автоматизація низькопріоритетних тестів. Замість того, щоб автоматизувати важливі частини функціоналу, команда може помилково обрати другорядні тести. У результаті ресурси витрачені дарма, тести не принесли суттєвої користі.
- Написання нестабільних автотестів. Були обрані невдалі селектори або ж нестабільне середовище. Як наслідок: тести постійно «падають», і їхнім результатам не можна довіряти.
- Відсутність інтеграції в CI/CD. Тести запускаються на локальному середовищі раз на місяць, і як результат вони просто не встигають перевіряти зміни, а баги потрапляють у продакшн.
- Відсутність підтримки автотестів. Тести були написані, але про них забули, тоді як продукт змінився. У результаті багато тестів «падають» із релізу в реліз.
- Відсутність структурованого коду. В автотестах не використовуються патерни (Page Object, DRY), постійно дублюється код. У результаті, при змінах в UI потрібно перезаписувати велику кількість тестів, що робить підтримку автоматизації занадто дорогою.
Відсутність code review. Перед тим як вважати тести якісними, їх варто перевіряти іншими членами команди. Свіжий погляд може допомогти знайти помилки або запропонувати кращі рішення.
Висновки
Хочу виділити головне для підсумку:
- Вимірюйте якість, а не кількість. Не зосереджуйтесь на числі тестів — головне, скільком багам вони реально допомогли запобігти й скільки часу зекономили команді.
- Автотести мають бути актуальними, щоб відображати реальний стан продукту.
- Немає сенсу автоматизувати всі кейси. У реальних умовах це неможливо й економічно невигідно. Автоматизація виправдана там, де вона економить час і гроші.
- Автоматизація не є самоціллю. Її головна мета — допомагати швидше й легше релізитися. Якщо цього не відбувається, підхід до автоматизації потрібно переглянути.
І найголовніше — ставтеся до автоматизації як до частини продукту, а не до тимчасових скриптів. Автотести — це система, яку потрібно розвивати й підтримувати. Лише в такому разі вони приноситимуть цінність у довгостроковій перспективі.
Сподобалась стаття? Підписуйтесь на автора, щоб отримувати сповіщення про нові публікації на пошту.

13 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів