vyvchy
    Теми розділу

    01 · Основи тестування

    Баг-репорт і життєвий цикл дефекту

    Зміст

    Розробник виправляє не той баг, який ти знайшов, а той, який ти описав. Тому баг-репорт (bug report, defect report) — найважливіший письмовий продукт тестувальника: знайти дефект — половина роботи, друга половина — донести його так, щоб хтось інший відтворив, зрозумів наслідки й виправив саме його. Погано описаний дефект живе довше і ходить по колу «не відтворюється — глянь ще раз», зʼїдаючи час двох людей.

    Баг-репорт — це асинхронна комунікація: його читатимуть без тебе, через тиждень, в іншому контексті, можливо — людина, яка ніколи не бачила цієї фічі. Тому кожне поле репорту існує не «для порядку в трекері», а відповідає на конкретне питання читача. Що таке дефект і чим він відрізняється від помилки та відмови — розібрано в базових поняттях; тут — що робити, коли дефект уже знайдено.

    Структура баг-репорту

    Назви полів різняться між трекерами (Jira, Azure DevOps, YouTrack), але набір стабільний, бо кожне поле закриває питання, без відповіді на яке фікс гальмує:

    ПолеНа яке питання відповідає
    ЗаголовокЩо зламалося, де і за яких умов — одним рядком
    Кроки відтворенняЯк мені побачити це в себе?
    Фактичний результатЩо саме сталося, з точним текстом помилки
    Очікуваний результатЩо мало статися і звідки це відомо (вимога, AC)
    СередовищеОточення, білд/версія, браузер, ОС — де саме це відбулося
    Серйозність (severity)Наскільки тяжкі технічні наслідки
    Пріоритет (priority)Наскільки терміново це виправляти
    АтачіДокази: скриншот, відео, логи, HAR

    Два поля заслуговують окремих слів.

    Заголовок — це те, за чим баг шукатимуть у трекері через пів року. Робоча формула: «що + де + за яких умов». Порівняй: «Не працює оплата» проти «Checkout: 500 при оплаті замовлення із застосованим промокодом». Перший заголовок змушує відкривати репорт, щоб зрозуміти, про що він; другий уже сам по собі — діагноз.

    Очікуваний результат — найчастіше недооцінене поле. «Має працювати коректно» — це порожнє місце: розробник не знає, що для тебе «коректно». Сильний очікуваний результат посилається на джерело істини — вимогу, acceptance criteria, макет чи усталену поведінку сусідніх фіч. Саме це поле перетворює «мені здається, тут не так» на «продукт порушує ось цю домовленість».

    Мінімальний робочий приклад цілком:

    Заголовок: Checkout: 500 при оплаті замовлення із застосованим промокодом
    
    Середовище: stage, білд 2.14.3, Chrome 138, macOS
    Severity: Critical    Priority: High    Частота: 5/5
    
    Передумови: у кошику один товар, промокод SUMMER10 застосовано
    
    Кроки:
    1. Відкрити /checkout
    2. Заповнити дані доставки валідними значеннями
    3. Натиснути «Сплатити»
    
    Фактичний результат: сторінка помилки; POST /api/orders повертає 500,
    тіло відповіді: {"error": "discount_id is null"}
    Очікуваний результат: замовлення створено, редірект на /order/confirmation
    (AC-3 у сторі ORD-214)
    
    Атачі: скриншот помилки, HAR, відео

    Зверни увагу на рядок «Частота: 5/5» — скільки разів дефект відтворився зі скількох спроб. Для стабільних багів це формальність, для плаваючих — критична інформація, яка чесно попереджає розробника, що з першої спроби може не вийти.

    І правило, яке економить найбільше: один дефект — один репорт. Три проблеми в одному тикеті означають, що після фікса першої тикет закриють, а дві решти загубляться.

    Кроки відтворення

    Кроки відтворення (steps to reproduce) — серце репорту. Хороші кроки мають три властивості:

    • Відтворюваність з нуля. Кроки починаються зі стану, який читач може створити сам: передумови явні (який користувач, які дані, який стан системи), а не «на моєму акаунті». Про стенди й білди, які фіксуються в передумовах, — глава про тестові середовища.
    • Конкретні дані. Не «ввести довге імʼя», а «ввести імʼя з 256 символів». Не «застосувати промокод», а «застосувати SUMMER10». Дефект часто живе саме в даних, і «будь-які» значення його не покажуть.
    • Мінімальність. Перед заведенням бага сценарій варто звузити: прибрати кроки й умови, без яких дефект однаково відтворюється. Якщо 500 на оплаті ловиться і без заповнення доставки — крок про доставку зайвий. Мінімальний сценарій не лише швидше перевіряти — він сам по собі підказує, де причина: усе, що лишилося в кроках, і є умовами прояву.

    Чим кроки в баг-репорті відрізняються від кроків у тест-кейсі: кейс описує заплановану перевірку, репорт — фактичний шлях до дефекту. Тому кроки репорту завжди конкретніші й вужчі — це не сценарій «перевірити оплату», а точний маршрут до однієї ями (структура тест-кейсу — у попередній главі).

    Severity vs priority

    Класика співбесід, яку питають майже завжди. Різниця проста, поки не змішувати дві осі:

    • Severity (серйозність) — наскільки тяжкі технічні наслідки дефекту для системи й користувача: краш, втрата даних, непрацююча функція, косметика. Зазвичай виставляє тестувальник, бо саме він бачив наслідки. Типова шкала: critical / major / minor / trivial (плюс blocker — коли дефект блокує саме тестування).
    • Priority (пріоритет) — наскільки терміново дефект треба виправити з погляду бізнесу. Виставляє той, хто відповідає за продукт і чергу робіт: продакт-менеджер або лід, часто на тріажі (triage) — регулярному розборі нових багів.

    Осі незалежні, тому реальні всі чотири комбінації:

    SeverityPriorityПриклад
    ВисокаВисокий500 при оплаті: checkout лежить у всіх користувачів, компанія втрачає гроші щохвилини
    ВисокаНизькийКраш при експорті річного звіту, який бухгалтерія формує раз на рік, — а до звітного періоду пів року
    НизькаВисокийОдрук у назві компанії на головній сторінці за день до запуску рекламної кампанії: технічно дрібниця, репутаційно — ні
    НизькаНизькийІконка зʼїхала на два пікселі у футері сторінки «Умови використання»

    Комбінації «висока severity + низький priority» і навпаки — улюблені на співбесідах, бо перевіряють, чи розумієш ти саме незалежність осей, а не завчив означення. Ключ до прикладів: severity дивиться на тяжкість наслідку, priority — на те, скільки людей і грошей це зачіпає зараз.

    Життєвий цикл дефекту

    Від заведення до закриття дефект проходить ланцюжок статусів. Конкретні назви залежать від трекера й процесу команди, але скелет однаковий усюди:

    тріаж, призначено розробнику

    не дефект

    уже заведено

    фікс відкладено

    виправлення потрапило в білд

    ретест пройшов

    ретест не пройшов

    Новий (New)

    В роботі (In Progress)

    Виправлено (Fixed)

    Закрито (Closed)

    Перевідкрито (Reopened)

    Відхилено (Rejected)

    Дублікат (Duplicate)

    Відкладено (Deferred)

    тріаж, призначено розробнику

    не дефект

    уже заведено

    фікс відкладено

    виправлення потрапило в білд

    ретест пройшов

    ретест не пройшов

    Новий (New)

    В роботі (In Progress)

    Виправлено (Fixed)

    Закрито (Closed)

    Перевідкрито (Reopened)

    Відхилено (Rejected)

    Дублікат (Duplicate)

    Відкладено (Deferred)

    Ключові точки маршруту:

    • New → тріаж. Свіжий баг спершу проходить розбір: чи дефект це взагалі, чи не дублікат, який пріоритет. Саме тут репорт «продає» себе — і саме тому якість опису вирішує.
    • Fixed → ретест. Розробник перевів баг у «виправлено» — це означає лише, що фікс потрапив у білд. Закриває баг тестувальник після ретесту на тому середовищі, куди фікс доїхав. Різниця між ретестом і регресією — у главі про смоук і регресію.
    • Reopened — лише якщо не виправлено те саме: ті самі кроки знову дають той самий фактичний результат. Якщо фікс зламав щось поруч — це новий дефект з новим репортом, а не reopen: у нового бага інші кроки, інша причина й, можливо, інший виконавець.

    Баг не відтворюється

    «Cannot reproduce» — не вирок і не привід мовчки закрити тикет. Дефект, який відтворюється нестабільно, нікуди не подівся — просто не всі умови його прояву потрапили в репорт. Систематичний перелік гіпотез, звідки береться різниця «у мене відтворюється — у розробника ні»:

    • Середовище. Інше оточення (test проти stage), інший білд, інша конфігурація. Перше, що звіряють, — рядок «Середовище» з репорту.
    • Дані та стан. У тебе користувач із промокодом і історією замовлень, у розробника — чистий акаунт. Стан бази часто і є «секретною» умовою відтворення.
    • Кеш. Браузер або CDN віддає стару версію фронтенду — у вас із розробником буквально різні застосунки. Як це працює і як діагностується — у главі про кешування.
    • Таймінги й гонки. Дефект проявляється лише на повільній мережі, при швидких кліках, при паралельних діях. Саме такі баги відтворюються «3 з 10» — і саме вони найболючіше стріляють у проді, бо там користувачів і паралельності більше, ніж на стенді.
    • Платформа. Браузер, його версія, ОС, розширення.

    Що робити практично: зафіксувати частоту спроб («відтворилося 2 з 10»), зібрати артефакти в момент прояву (скриншот, HAR, логи з часовою міткою — щоб бекенд-лог можна було зіставити з моментом помилки) і додати все це в репорт. Якщо дефект впіймано один раз і більше ніяк — чесний варіант: репорт з усіма доказами й позначкою про частоту. Один раз побачений 500 з тілом відповіді в атачі — це вже зачіпка для розробника в серверних логах, навіть без стабільного відтворення.

    Duplicate, rejected, won't fix

    Не кожен баг завершується фіксом — і це нормальні, а не «поразкові» фінали:

    • Duplicate (дублікат) — такий дефект уже заведено. Ліки профілактичні: перед заведенням пошукати в трекері за ключовими словами й текстом помилки. Якщо дублікат усе ж стався — тикети лінкують: два незалежні прояви — корисна інформація про частоту.
    • Rejected / not a bug — поведінка відповідає вимогам (works as designed), або «дефект» виявився нерозумінням фічі. Перший крок при незгоді — перечитати вимогу: можливо, права саме вона. Якщо вимога мовчить — це вже інша знахідка: дірка у вимогах, і її теж варто зафіксувати.
    • Wonʼt fix — дефект визнано, але виправляти не будуть: вартість фікса вища за шкоду, фіча доживає останні місяці, кейс екзотичний. Це бізнес-рішення про пріоритети, а не оцінка твоєї роботи. Задача тестувальника — щоб рішення ухвалювалося з повною картиною наслідків, і щоб воно лишилося зафіксованим письмово: коли дефект вистрелить у проді, історія «ми знали і свідомо відклали» звучить зовсім інакше, ніж «ніхто не знав».
    • Deferred (відкладено) — проміжний варіант: виправлять, але не в цьому релізі.

    Аргументація без емоцій

    Баг-репорт і коментарі під ним читають люди — і найкращий опис дефекту можна знецінити одним пасивно-агресивним рядком. Кілька правил, які відрізняють професійну комунікацію від сварки в трекері:

    • Факти замість оцінок. «POST /api/orders повертає 500 при застосованому промокоді» — факт. «Знову все зламали після деплою» — оцінка, яка гарантовано переведе розмову з дефекту на тон. Репорт описує поведінку продукту, а не якість чиєїсь роботи.
    • Вплив замість гучності. Severity не «підвищують», щоб баг помітили. Якщо вважаєш дефект важливішим, ніж його оцінила команда, — принеси дані: скільки користувачів проходить цей сценарій, що саме вони втрачають, як часто відтворюється. Аргумент «це блокує головний сценарій покупки для всіх користувачів з промокодом» працює; аргумент «та це ж очевидно критично!» — ні.
    • Питання замість звинувачень. «Не баг» від розробника — початок діалогу, а не стіна: «Дивись, в AC-3 написано ось так, а поводиться ось так — я щось пропускаю?» Часто зʼясовується, що обидва праві: код відповідає вимозі, а вимога — застаріла.
    • Ескалація — через процес, не через голос. Якщо після обговорення згоди немає, рішення ухвалює той, хто володіє пріоритетами (продакт, лід) — і будь-яке його рішення, включно з wonʼt fix, фіксується в тикеті. Тестувальник відповідає за те, щоб ризик був видимий, а не за те, щоб кожен його баг був виправлений.

    Атачі: логи, скриншоти, відео, HAR

    Правильний атач скорочує шлях від «бачу симптом» до «бачу причину». У кожного типу своя робота:

    • Скриншот — найшвидший доказ «що сталося». Стрілка чи рамка на місці проблеми обовʼязкова: без анотації читач шукатиме дефект по всьому екрану. Скриншот показує наслідок, але не шлях — тому він доповнює кроки, а не замінює їх.
    • Відео — для дефектів, де важлива послідовність або таймінг: щось блимнуло, зникло, стрибнуло. Коротке, від передумови до фактичного результату.
    • Логи — консоль браузера для фронтенд-помилок, серверні логи для 5xx. Головне в логах — часова мітка: вона дозволяє зіставити твій прояв бага з записами на бекенді. Якщо у відповідях API є ідентифікатор запиту (request id) — він у репорті безцінний.
    • HAR (HTTP Archive) — JSON-файл з повним записом мережевої активності вкладки: усі запити з заголовками, тілами, статусами й таймінгами. Експортується з вкладки Network у DevTools (як саме — у главі про DevTools). Для багів рівня «фронт-бек» HAR — найсильніший атач: розробник бачить точний запит і точну відповідь, а не переказ. Важливе застереження: HAR містить cookie, токени й тіла запитів — перед прикріпленням у трекер (тим паче публічний) чутливі дані треба вичистити.

    В автотестах ті самі артефакти збираються автоматично. Playwright уміє писати HAR і відео на рівні контексту, а його трейс (trace) — це скриншоти, дії, мережа й консоль в одному файлі, готовий атач до баг-репорту з CI:

    const context = await browser.newContext({
      recordHar: { path: 'artifacts/checkout.har' },
      recordVideo: { dir: 'artifacts/videos/' },
    });

    Принцип відбору атачів простий: скриншот відповідає на «що видно», відео — на «як до цього дійшло», логи й HAR — на «що при цьому відбувалося під капотом». Для UI-косметики досить скриншота; для 500 на оплаті — HAR і лог з міткою часу.

    Типові помилки

    • Виглядає як економія часу — три проблеми в одному репорті, а насправді після фікса першої тикет закриють, а дві решти загубляться без сліду. Один дефект — один репорт.
    • Виглядає як «баг важливий, тому ставлю високу severity», а насправді severity — про технічні наслідки, а «наскільки терміново» — це priority, і виставляє його той, хто керує чергою робіт. Змішування осей — найчастіший провал на співбесіді.
    • Виглядає як очікуваний результат — «має працювати коректно», а насправді це порожнє поле: без посилання на вимогу, AC чи усталену поведінку читач не знає, що таке «коректно» для тебе.
    • Виглядає як «не відтворилося двічі — закриваю», а насправді нестабільне відтворення — типовий почерк гонок і залежності від даних. Такий дефект не зник — він просто чекає на прод.
    • Виглядає як «скриншот усе пояснює», а насправді скриншот без кроків і середовища — це загадка: видно наслідок, невідомо ні шляху, ні місця, ні версії.
    • Виглядає як привід для reopen — «фікс зламав сусідню фічу», а насправді це новий дефект з новими кроками. Reopen — лише коли ті самі кроки знову дають той самий результат.
    • Виглядає як чесність — «знову нічого не працює» у заголовку, а насправді емоційна оцінка замість фактів переводить обговорення з дефекту на стосунки. Продукт зламаний — репорт спокійний.

    Підсумок

    • Баг-репорт пишеться для людини, яка відтворюватиме дефект без тебе: конкретні кроки з даними, фактичний результат з текстом помилки, очікуваний результат із джерелом (вимога/AC), точне середовище й білд.
    • Severity — технічний вплив, ставить тестувальник; priority — терміновість для бізнесу, ставить власник пріоритетів. Осі незалежні: реальні всі чотири комбінації, і на співбесіді чекають прикладів, а не означень.
    • Життєвий цикл: New → тріаж → In Progress → Fixed → ретест → Closed, з бічними гілками rejected/duplicate/deferred/wonʼt fix. Закриває дефект тестувальник після ретесту, а не розробник після коміту.
    • «Не відтворюється» — це брак умов у репорті, а не відсутність дефекту: звіряй середовище, дані, кеш і таймінги, фіксуй частоту спроб і збирай артефакти в момент прояву.
    • Атачі відповідають на різні питання: скриншот — «що видно», відео — «як дійшло», логи й HAR — «що під капотом». HAR містить cookie й токени — чисти перед прикріпленням.

    Що питають на співбесіді

    • «Чим severity відрізняється від priority? Наведи приклад бага з високою severity і низьким priority — і навпаки.» Класика номер один. Інтервʼюер чекає не означень, а живих прикладів на обидві «перехресні» комбінації: саме вони показують, що ти розумієш незалежність осей.
    • «Опиши життєвий цикл дефекту.» Дивляться, чи знаєш ти більше за happy path: гілки rejected/duplicate/deferred, хто переводить між статусами і чому закриває баг тестувальник після ретесту, а не розробник після фікса.
    • «З чого складається хороший баг-репорт?» Сильна відповідь пояснює «навіщо» кожного поля (для кого воно і яке питання закриває), а не перелічує назви полів. Бонус — правило «один дефект — один репорт» і згадка про частоту відтворення.
    • «Баг не відтворюється в розробника. Твої дії?» Перевіряють системність: перелік гіпотез (середовище, білд, дані, кеш, таймінги), збір артефактів з часовими мітками, чесна фіксація частоти — а не «попрошу подивитися ще раз» чи «закрию».
    • «Розробник каже, що це не баг. Що робитимеш?» Питання про зрілість, а не про впертість: спершу вимоги, потім уточнення в автора рішення, далі — дані про вплив, і ескалація через власника пріоритетів. Червоний прапорець для інтервʼюера — «доводитиму, поки не визнають».
    • «Що прикладеш до бага про помилку оплати?» Чекають розуміння, який артефакт яке питання закриває, і згадки про HAR для клієнт-серверних багів — з застереженням про чутливі дані в ньому.

    Джерела

    • ISTQB CTFL Syllabus v4.0 — глава покриває розділ 5.5 «Defect Management»: цілі управління дефектами і зміст defect report.
    • Глосарій ISTQB — канонічні означення термінів: defect, defect report, defect management, severity, priority.
    • Chrome DevTools: Network panel reference — робота з вкладкою Network, зокрема запис і експорт HAR.
    • Playwright: Trace Viewer — трейс як готовий пакет артефактів (дії, скриншоти, мережа, консоль) для розбору фейлу й баг-репорту.