Навіщо тестувальнику читати код?
Чи може захисник футбольної команди нападати? Так. А чи може тестувальник читати код девелоперів? Це питання спонукає замислитися не лише новачків, а й досвідчених експертів. Бо зазвичай на IT-проєктах не прийнято виходити за рамки звичних інструкцій. Та в кожному правилі є винятки.
Сергій Могилевський, QA Team Lead и Tech Lead в NIX, доводить ефективність інженерного підходу в тестуванні на прикладах. І якщо ви досі вагаєтесь, чи потрібно QA-інженеру читати код, ознайомтесь із детальними поясненням нижче.
Навіщо це потрібно та яку користь можна отримати з інженерного підходу?
- Глибше зрозуміти програму, яку тестуєте. Знаючи, як саме працює застосунок, ви можете створювати більш ефективні тести.
- Запобігти блокуванню тестування. Функціонал без чітко прописаних вимог — стоп у роботі тестувальника. Але QA-інженер може зрозуміти, як працює нова фіча, розібравшись з її реалізацією в коді.
- Докладніше описувати баги. Розуміння того, як влаштована програма, допомагає створювати інформативні баг-репорти і описувати помилки не лише з точки зору користувача. Завдяки цьому девелопери у вашій команді не витрачатимуть час на вивчення проблеми.
- Писати якісний код для автоматизованого тестування. Читання хороших книг допомагає влучно формулювати думки. Вивчення добре написаного коду сприяє опануванню підходів, які спрощують повсякденну роботу.
А тепер про все це — на прикладах
Припустимо, що для бекенду нашого застосунку розробники використовують популярний фреймворк SpringBoot. Погугливши дізнаємось, що стандартна структура проєкту на цьому фреймворку виглядає приблизно так:
Чудово! Тепер ми трохи розуміємо структуру, але залишаються незрозумілими слова: controller, service, repository та model. Знову звертаємося до гугла та з’ясовуємо, що:
- Controller — це клас, який обробляє одержувані запити і переправляє їх «углиб» програми, свого роду вхідна точка;
- Model — опис структури сутностей, із якими готовий працювати застосунок;
- Service — це клас, в якому описується бізнес-логіка конкретної сутності;
- Repository — код, який взаємодіє з базою даних.
Усе ще нічого не зрозуміло? А якщо так?
- Controller — це те, як ми звертаємося до застосунку;
- Model — показує, які дані від нас очікуються під час звернення;
- Service — те, що програма робитиме, коли ми успішно звернулися до неї;
- Repository — місце, де зберігатимуться оброблені дані.
Так, здається, вже простіше. Тепер справа за малим — використати все це на практиці.
Немає документації для доступних у мікросервісі ендпоінтів? Не біда, просто йдемо дивитися контролери. Знаходимо перелік усіх доступних ендпоінтів для кожної сутності:
Потрібно дізнатися структуру об’єкта, який ми будемо туди передавати? Йдемо в код моделі цього об’єкта і бачимо перелік усіх полів:
Наведений вище код знадобився нам для прикладу. У реальному ж проєкті код вашого застосунку може виявитись не настільки тривіальним. Але якщо спостерігати за його розвитком у динаміці, то проблем виникнути не має. До речі, є приємний бонус для вас. Сучасна розробка виконується з використанням відносно невеликої кількості архітектур. Досить велика кількість фреймворків на різних мовах мають схожу структуру саме через те, що вони імплементують одну й ту саму архітектуру. Тобто один раз вивчаєте її, а потім розглядаєте в коді застосунку.
Наведу ще один приклад на користь самостійного вивчення коду. Уявімо, що ви як QA не можете продовжити тестування продукту тому, що частина функціоналу не працює. Наприклад, вказаний у вимогах параметр REST endpoint на бекенді недоступний. Що в такому випадку може зробити тестувальник?
Спробує різні варіанти цього параметру. Якщо успіху немає, звернеться за допомогою до розробника, і вони разом спробують розв’язувати проблему. Здавалося б, очевидний і простий спосіб, але він має недоліки:
- Розробнику доведеться витратити час на те, щоб пояснити тестувальнику суть проблеми.
- Тестувальник стає «залежним» від розробника і не може сам впоратися із завданням.
- Спілкування з девелопером може замилити око недосвідченому тестувальнику. В результаті фактично розроблений функціонал він буде вважати еталонним. На його основі і буде розроблятися стратегія тестування (можливо, за умови нечітко прописаних вимог).
Я радив би діяти інакше. Якщо під час тестування ви помітили помилку, знайдіть відповідний тікет, наприклад, у Jira, з вказаним там автором тестованої фічі. Там ви знайдете Pull Request — набір змін до кодової бази в межах цього таску. Ви побачите, які зміни та в який рядок коду вносив кожен з учасників команди. Маючи більше контексту, вам буде простіше зрозуміти, чому система вказала на неправильний параметр на бекенді.
Плюси для тестувальника очевидні:
- у спеціаліста формується надивленість шляхом аналізу коду;
- замість спільного пошуку помилок ви заощаджуєте час колег та свій особистий;
- у майбутньому зможете підібрати різні варіанти тестування для кожної нової функціональності.
На мій погляд, описана практика потенційно підвищить якість тестування та допоможе вам стати самостійнішим. Не обмежуйте себе монотонними завданнями, руйнуйте стереотипи про роботу QA. Завжди прагніть глибше розібратися у предметній галузі. І тоді якість продуктів, які ви тестуєте, зросте в рази.