Conceptual Vector Flat Illustration of a Man With Laptop Depicting His Advanced Skills in Programming
«Сюди не лізь», «Це не чіпай», «Це для тебе занадто складно», «А це ти може і зрозумієш, але нескоро». Звучить, як слова суворих батьків, які намагаються захистити свою дитину від усього нового, незрозумілого і, не дай боже, цікавого. І знаєте, що? На жаль, багато людей переносять такий підхід у свою роботу.
Тоді нічого, що виходить за межі робочих інструкцій, не те, що «не хочеться», а взагалі «не можна» робити.
Навчатися новому стає страшно і здається, ніби колеги можуть засудити за проактивність, але точно не заохотити чи схвально оцінити ваші старання.
Особисто я ніколи не розділяв такий підхід. Будучи ментором, у роботі зі своїми підопічними я завжди намагаюся зробити так, щоб усе було можна, цікаво та відкрито для вивчення. У цій статті я спробую на прикладі окремо взятої практики пояснити, що вивчати нове — це корисно, а розширювати своє коло відповідальності за власною ініціативою — зовсім не страшно.
Перейдемо від лірики до конкретних понять. Інженерний підхід до тестування може змінити вміння читати код. Можливо, прозвучить банально, але часто QA-інженери забувають про це.
На лекції в межах NIX MultiСonf я згадував про переваги ситуації, коли QA не лише вміє писати тестовий код, а ще й не соромиться самостійно вивчати код, який пишуть розробники. Зазвичай це можливо, коли команда розробки використовує для своїх активностей ту саму мову програмування, що й тестувальники для автоматизації.
Написані тест-кейси та тести стають більш раціональними за рахунок того, що ви краще розумієте, як працює застосунок, і відповідно — те, як його тестувати.
Якщо функціонал, який потрібно протестувати, недостатньо покритий вимогами (що само собою, звичайно, є проблемою, яку треба вирішувати окремо), то QA-інженер все одно зрозуміє, як працює нова фіча, подивившись на її реалізацію в коді.
Знайшовши проблему в застосунку, QA може не тільки описати кроки з точки зору користувача, але й глибше проаналізувати їх, вивчивши код, який стосується «проблемної» фічі. Зі знайденою інформацією ви зможете вести більш інформативний баг-репорт. Прочитавши такий документ, розробник швидше зможе все пофіксити. А це вже заощадить значну частину часу, яку девелопер міг витратити на інвестігейт проблеми.
Читання хороших книг допомагає гарно формулювати думки. Слідкування за модними тенденціями покращує вміння одягатися зі смаком. За аналогією — читання добре написаного коду дозволяє писати більш чистий, зрозумілий і правильний код самостійно. Відповідно, чим частіше автоматизатор читає код розробників, тим більше він черпає корисних практик і підходів для своєї повсякденної роботи.
Варто підкреслити, що попри всі плюси цього підходу я б не радив умовному QA manual вивчати програмування виключно для того, аби читати девелоперський код. Цей скілл більше стосується тих, хто і так використовує програмування у вирішенні своїх завдань. Наприклад, тих самих QA automation та іноді General QA.
Ще на старті розробки рекомендую озвучити в команді важливий момент: код за замовчуванням буде спільним.
Не має існувати бар’єрів, через які розробник ніколи не захоче читати автотести, а тестувальник — вихідний код програми.
Ініціативу пропоную взяти на себе саме тестувальнику.
Для початку дізнаємося, на якому фреймворку планують писати застосунок. Про це розповість будь-хто з розробників. Також можна звернутися до документації на умовному Confluence. Залежно від типу програми (з/без GUI, десктоп/мобайл/веб тощо) фреймворків може бути декілька.
Далі потрібно поринути на декілька днів у гугл і вивчити те, що буде нас цікавити у подальшій роботі:
Після ресьорчу можете спробувати зробити простенький приклад, щоб краще зрозуміти те, що відбувається. Коли почнеться активна розробка фіч, за наявності вільного часу подивіться код пул-реквестів, який будуть викладати девелопери, і спробуйте осягнути все, що там написано.
Дуже швидко виявиться, що всі типові конструкції, які ми вивчили напередодні, будуть добре виділятися на тлі усього написаного коду. Тепер у коді, скажімо, мікросервісу ви зможете легко знайти, наприклад, список доступних ендпоінтів чи полів, які потрібно чи, навпаки, не треба відправляти на кожен із них, щоб він відпрацював. Саме час застосувати ці знання в процесі тестування!
Припустимо, що для бекенду нашого застосунку розробники використовують популярний фреймворк SpringBoot. Погугливши дізнаємось, що стандартна структура проєкту на цьому фреймворку виглядає приблизно так:
кореневийПакет +- щеПакет +- назваЗастосунку +- ГоловнийКлас.java | +- пакетСутності1 | +- Сутність1.java | +- Сутність1Controller.java | +- Сутність1Service.java | +- Сутність1Repository.java | +- Сутність1Model.java | +- пакетСутності2 +- Сутність2.java +- Сутність2Controller.java +- Сутність2Service.java +- Сутність2Repository.java +- Сутність2Model.java
Чудово! Тепер ми трохи розуміємо структуру, але залишаються незрозумілими слова: controller, service, repository та model. Знову звертаємося до гугла та з’ясовуємо, що:
Усе ще нічого не зрозуміло? А якщо так?
Так, здається, вже простіше. Тепер справа за малим — використати все це на практиці.
Немає документації для доступних у мікросервісі ендпоінтів? Не біда, просто йдемо дивитися контролери. Знаходимо перелік усіх доступних ендпоінтів для кожної сутності:
@RestController @RequestMapping("/api/subject") @RequiredArgsConstructor @Slf4j public class SubjectController { private final CommandDispatcher commandDispatcher; @PostMapping("") public ResponseEntity<CommandResult<String>> create(@RequestBody @Valid CreateSubjectCommand command) { … } @PutMapping("/{id}") public ResponseEntity<CommandResult<String>> update(@PathVariable String id, @RequestBody @Valid UpdateSubjectCommand command) { … } @PutMapping("/{id}/rate") public ResponseEntity<CommandResult<String>> rate(@PathVariable String id, @RequestBody @Valid RateSubjectCommand command) { … }
Потрібно дізнатися структуру об’єкта, який ми будемо туди передавати? Йдемо в код моделі цього об’єкта і бачимо перелік усіх полів:
@Data @Builder @Document(collection = "subjectStore") public class SubjectModel { @Id private final String id; private final Date timeStamp; private final String aggregateIdentifier; private final String aggregateName; private final int version; private final String subjectName; private final BaseSubject subjectData; }
Наведений вище код знадобився нам для прикладу. У реальному ж проєкті код вашого застосунку може виявитись не настільки тривіальним. Але якщо спостерігати за його розвитком у динаміці, то проблем виникнути не має. До речі, є приємний бонус для вас. Сучасна розробка виконується з використанням відносно невеликої кількості архітектур. Досить велика кількість фреймворків на різних мовах мають схожу структуру саме через те, що вони імплементують одну й ту саму архітектуру. Тобто один раз вивчаєте її, а потім розглядаєте в коді застосунку.
Наведу ще один приклад на користь самостійного вивчення коду. Уявімо, що ви як QA не можете продовжити тестування продукту тому, що частина функціоналу не працює. Наприклад, вказаний у вимогах параметр REST endpoint на бекенді недоступний. Що в такому випадку може зробити тестувальник?
Спробує різні варіанти цього параметру. Якщо успіху немає, звернеться за допомогою до розробника, і вони разом спробують вирішити проблему. Здавалося б, очевидний і простий спосіб, але він має недоліки:
Я радив би діяти інакше. Якщо під час тестування ви помітили помилку, знайдіть відповідний тікет, наприклад, у Jira, з вказаним там автором тестованої фічі. Там ви знайдете Pull Request — набір змін до кодової бази в межах цього таску. Ви побачите, які зміни та в який рядок коду вносив кожен з учасників команди. Маючи більше контексту, вам буде простіше зрозуміти, чому система вказала на неправильний параметр на бекенді.
Плюси для тестувальника очевидні:
На мій погляд, описана практика потенційно підвищить якість тестування та допоможе вам стати самостійнішим. Не обмежуйте себе монотонними завданнями, руйнуйте стереотипи про роботу QA. Завжди прагніть глибше розібратися у предметній галузі. І тоді якість продуктів, які ви тестуєте, зросте в рази.
Читайте також: «Головне — зрозуміти основи, далі буде легше»: скільки мов програмування потрібно знати тестувальнику
Дуже хочеться робити якісь десктопні апки. Сумую за часами коли всі програми були offline-first, і…
Надсилаючи криптовалюту, багато новачків ставлять запитання: як працюють комісії та чому вони відрізняються в різних…
Нова афера набирає обертів — ось детальний розбір того, як фальшиві потенційні роботодавці намагаються вкрасти…
Соцмережа з можливістю вбудовувати повноцінні додатки прямо в пости — звучить як фантастика, але Farcaster…
Я ніколи в житті не був на співбесіді «по ту сторону». Мене ніхто не запрошував…
Я багато писав про fly.io — тоді ще новачка на ринку IaaS/PaaS хостингу. Я й…