QA на практиці
Реальні баг-репорти, інтерактивний запуск тестів і зрозумілі QA-артефакти, які показують як ми знижуємо ризик релізу до виходу в продакшн.
Реальні приклади QA
Ця сторінка працює як короткий proof-pack: замість абстрактних обіцянок ви одразу бачите формат баг-репортів, рівень деталізації та якість QA-артефактів, з якими працюватиме ваша команда.
Як ми оформлюємо знахідки
Проблема
Фіксуємо проблему, контекст, середовище та кроки відтворення без двозначності.
Вплив
Пояснюємо, що саме ламається для користувача, бізнесу або релізу.
Рекомендація
Даємо безпечніші напрями виправлення та що перевірити після змін.
Повторна перевірка
Після фіксу перевіряємо сценарій повторно і підтверджуємо реальний статус.
Приклади баг-репортів
Таймаут платіжного шлюзу
Оплата не проходить, коли відповідь провайдера займає більше 15 секунд. Користувачі втрачають замовлення та гроші.
- Додати товар до кошика
- Перейти до оформлення
- Ввести дані картки
- Натиснути "Оплатити" на повільному з'єднанні
- Збільшити таймаут до 30 секунд
- Додати механізм повторів (3 спроби)
- Показувати індикатор прогресу
Processing продовжує пошук транзакцій після відхилення Travel Rule
Сервіс processing-service продовжує пошук і обробку транзакцій навіть після того, як сервіс Travel Rule повертає статус відхилення (DECLINED).
- Створити інвойс або транзакцію
- Дочекатися запуску перевірки Travel Rule
- Повернути відповідь DECLINED від сервісу Travel Rule
- Перевірити логи processing-service та активність черг
- Переконатися, що пошук транзакції продовжується після відхилення
- Негайно завершувати transaction-search після статусу DECLINED
- Додати early-stop механізм для processing pipeline
- Блокувати створення нових processing jobs після відмови Travel Rule
- Додати guard-check перед кожним етапом обробки транзакції
- Логувати причину зупинки processing flow
- Покрити сценарій integration та e2e тестами
Polygon RPC provider повертає некоректні block data
Polygon RPC провайдери (Infura, Alchemy, GetBlock) періодично повертають
некоректні block payloads, які не проходять десеріалізацію через
DeserError: BlockTransactions під час обробки блоків.
- Підключитися до Polygon RPC через Infura або Alchemy
- Запросити block data через
eth_getBlockByNumber - Спробувати десеріалізувати
BlockTransactions - Перевірити появу періодичних
DeserError
DeserError, через що RPC backend пропускає частину блоків.
- Оновити логіку десеріалізації транзакцій для підтримки EIP-4844
- Додати fallback parsing для невідомих transaction variants
- Реалізувати retry та provider failover для некоректних RPC-відповідей
- Логувати номери проблемних блоків і відповіді провайдерів
- Валідувати RPC payload schema перед обробкою транзакцій
- Покрити blob transaction сценарії regression та integration тестами
Crypto invoice очікує повний timeout без виявленого депозиту
Crypto invoices залишаються у стані AwaitingCryptoDeposit
до повного expires_at timeout (5-10+ годин), навіть якщо
blockchain transaction так і не була виявлена, що створює поганий UX
у payment widget.
- Створити crypto invoice та відкрити payment widget
- Перевірити стан
AwaitingCryptoDeposit - Не надсилати crypto transaction
- Дочекатися завершення deposit detection window
- Переконатися, що invoice продовжує очікування до
expires_at
"Transaction still not found", тоді як
widget продовжує показувати "awaiting payment".
expires_at timeout повинен застосовуватися лише після
виявлення транзакції.
- Реалізувати two-tier timeout логіку для crypto invoices
- Додати early expiry для invoices без знайдених транзакцій
- Зберігати можливість cancel під час deposit detection window
- Не завершувати invoice, якщо oracle-pool вже виявив in-flight transaction
- Відписувати oracle-pool listeners при будь-якому expiry state
- Винести invoice timeout values у configurable environment variables
GetInvoice повертає 500 після oracle-pool callback
Після отримання oracle-pool callback endpoint
GetInvoice повертає
500 Internal Server Error замість коректного invoice object.
- Створити invoice через
PaymentInvoicesService.CreateInvoice - Переконатися, що invoice має стан
pending.awaiting_crypto_deposit - Викликати
GetInvoiceта перевірити, що endpoint працює до callback - Надіслати
POST /v1/callbacks/oracle-poolзіstatus=1таconfirmations=1 - Повторно викликати
GetInvoiceдля того жinvoice_id
GetInvoice повертає
500 Internal Server Error після обробки oracle-pool callback.
GetInvoice повинен повертати коректний invoice object
з оновленим статусом:
pending.awaiting_checks,
pending.awaiting_exchange
або expired.
- Перевірити invoice state transitions після oracle-pool callback
- Додати null та schema validation перед invoice serialization
- Логувати callback payloads та invoice state mutations для debugging
- Не допускати некоректні invoice states до GetInvoice response mapping
- Додати fallback error handling для malformed callback data
- Покрити callback-to-GetInvoice flow integration та regression тестами
Токен сесії в URL
Токен аутентифікації видно в адресному рядку браузера, що дозволяє перехоплення через історію браузера або логи проксі.
- Натиснути "Увійти через Google"
- Завершити OAuth авторизацію
- Перевірити URL після редіректу
site.com/home?token=abc123
- Прибрати токен з URL параметрів
- Використовувати secure cookie з SameSite=Strict
- Перевірити логи доступу на наявність токенів
Накладання меню на iPhone SE
Пункти меню навігації накладаються один на одного на екранах менше 375px
- Відкрити сайт на iPhone SE
- Натиснути на меню-бургер
- Подивитися розташування пунктів меню
- Додати media query для екранів <375px
- Зменшити розмір шрифту або відступи
- Тестувати на реальному iPhone SE
Втрата чернетки після оновлення сторінки
Останні зміни в довгій формі зникають, якщо користувач оновлює сторінку під час затримки автозбереження.
- Відкрити довгу форму з автозбереженням
- Вводити дані 20-30 секунд
- Оновити сторінку під час синхронізації
- Зберігати несинхронізований стан локально
- Додати індикатор стану синхронізації
- Попереджати перед перезавантаженням за наявності незбережених змін
Ескалація прав через кеш ролей
Після відкликання адмін-прав користувач ще певний час може виконувати захищені дії.
- Зняти роль адміністратора з існуючого користувача
- Не завершувати поточну сесію
- Спробувати виконати адмін-дії
- Інвалідувати кеш ролей після оновлення прав
- Перевіряти ролі серверно для чутливих дій
- Логувати спроби доступу після revoke
Подія покупки не потрапляє в аналітику
Успішне замовлення створюється, але подія покупки не відправляється після оформлення в один клік.
- Запустити оформлення в один клік зі збереженою карткою
- Успішно завершити оплату
- Перевірити мережеві запити й дашборд аналітики
- Запускати аналітику тільки після підтвердженого backend-успіху
- Додати сповіщення про просідання подій покупки
- Покрити checkout-сценарії окремим regression-набором
Скидання фільтрів після пагінації каталогу
Після переходу на другу сторінку каталогу активні фільтри зникають, а список товарів змінюється без попередження.
- Відкрити каталог товарів
- Застосувати 2-3 фільтри й сортування
- Перейти на другу сторінку результатів
- Додати фільтри в URL параметри
- Використовувати History API для навігації
- Зберігати стан фільтрів в sessionStorage
PDF-рахунок доступний після виходу з акаунта
Посилання на інвойс продовжує відкривати документ навіть після завершення сесії користувача.
- Увійти в акаунт і відкрити історію рахунків
- Скопіювати пряме посилання на PDF
- Вийти з акаунта й відкрити посилання в новій вкладці
- Перевіряти авторизацію на рівні файлового ендпоінта
- Використовувати короткоживучі підписані URL
- Додати аудит доступу до чутливих документів
SQL-ін'єкція в пошуковому полі
Поле пошуку не екранує спецсимволи, дозволяючи виконання довільних SQL-запитів.
- Відкрити каталог товарів
- Ввести в пошук:
'; DROP TABLE orders; -- - Натиснути Enter
- Використовувати параметризовані запити (prepared statements)
- Додати валідацію введення на рівні API
- Ввімкнути WAF правила для SQL-ін'єкцій
XSS через поле відгуку
Відгуки користувачів відображаються без ескейпінгу HTML, дозволяючи виконання скриптів.
- Відкрити будь-який товар
- Додати відгук з текстом:
<script>alert('XSS')</script> - Зберегти відгук
- Використовувати textContent замість innerHTML
- Додати CSP заголовки
- Провести аудит всіх місць виводу користувацьких даних
Відсутність обмеження частоти запитів на API
API-ендпоінт для зміни пароля не має обмежень на кількість запитів.
- Відправити запит на зміну пароля
- Повторити запит 100+ разів за хвилину
- Перевірити відповіді сервера
- Додати rate limiting (5 запитів на хвилину)
- Впровадити exponential backoff
- Логувати підозрілу активність
Завантаження виконуваних файлів
Форма завантаження аватару приймає будь-які типи файлів включно з .exe та .php.
- Відкрити налаштування профілю
- Вибрати файл shell.php замість зображення
- Завантажити файл
- Валідувати MIME-тип і розширення файлу
- Перевіряти magic bytes файлу
- Зберігати файли поза web-root з перейменуванням
Повторне списання після повторної оплати
Якщо користувач повторно натискає оплату після довгої відповіді провайдера, створюються два успішні списання для одного замовлення.
- Оформити замовлення з банківською карткою
- Дочекатися затримки відповіді платіжного провайдера
- Повторно натиснути кнопку "Оплатити"
- Додати idempotency key для кожного платіжного запиту
- Блокувати кнопку після першого кліку до відповіді провайдера
- Окремо логувати дубльовані webhooks і reconciliation case
Некоректне округлення суми при частковій оплаті
При частковій оплаті з бонусами підсумкова сума в checkout відрізняється від суми, яка передається в платіжний провайдер.
- Додати товар з копійками до кошика
- Застосувати бонусний баланс на частину суми
- Перейти до підтвердження оплати карткою
- Уніфікувати правила округлення між клієнтською і серверною частинами
- Працювати з мінімальними грошовими одиницями замість чисел з плаваючою комою
- Додати автотести для бонусних і змішаних оплат
Подія повернення не потрапляє в аналітику
Після успішного refund в адмін-панелі подія повернення не потрапляє ні в GA4, ні у внутрішній фінансовий дашборд.
- Відкрити оплачений order в адмін-панелі
- Виконати часткове або повне повернення
- Перевірити аналітичні події та BI-дашборд
- Відправляти окрему refund event після підтвердження backend статусу
- Додати моніторинг розриву між orders і refunds в аналітиці
- Покрити refund flow окремим regression сценарієм
Втрата UTM-міток після входу в акаунт
Після логіну користувача атрибуція кампанії скидається, і замовлення потрапляють у звітність як direct / none.
- Відкрити лендинг з UTM-мітками
- Перейти до товару та увійти в акаунт
- Завершити checkout і перевірити source / medium
- Зберігати attribution state у sessionStorage або server session
- Не перезаписувати source після auth redirect
- Додати перевірки для login-to-checkout funnel
Демо запуску автотестів
Подивіться, як виглядає запуск демо-набору автотестів: зі статусами, сигналами ризику, підсумком і переходом до прикладу реального QA-звіту.
Що це показує: типовий сценарій перевірки оформлення замовлення зі статусами проходження, попередженнями та сигналами, що допомагають не випустити ризиковий реліз.
Натисніть кнопку, щоб побачити не лише підсумок, а й приклад конкретних знахідок у звіті
Приклади тест-кейсів
- Відкрити сторінку входу
- Ввести валідний email
- Ввести валідний пароль
- Натиснути кнопку "Увійти"
- Відкрити сторінку товару
- Вибрати розмір/колір якщо потрібно
- Натиснути "Додати до кошика"
- Перевірити оновлення значка кошика
- Ввести неіснуючий email
- Натиснути "Відправити посилання"
- Спостерігати відповідь системи
- Відкрити оформлення в один клік
- Успішно завершити оплату
- Перевірити мережеві запити та події аналітики
- Зняти роль адміністратора з користувача в іншій сесії
- Повернутися до поточної адмін-сесії
- Спробувати змінити білінг або ролі інших користувачів
- Внести зміни в кілька полів форми
- Не чекати завершення автозбереження
- Спробувати оновити сторінку або перейти на інший розділ
Що ви отримуєте в реальній співпраці
Ці приклади спрощені, але сама структура в реальних проєктах така ж: відтворювані докази, зрозумілі пріоритети, бізнес-вплив і рекомендації, які команда може брати в роботу одразу.
Пріоритезовані знахідки
Кожен баг групується за критичністю та впливом, щоб команда одразу бачила, що блокує реліз, а що можна планувати окремо.
Чіткі кроки відтворення
Оточення, кроки, очікуваний і фактичний результат прибирають неоднозначність і економлять час розробки.
Практичні рекомендації
Ми не зупиняємось на фразі “зламано”, а підказуємо зони ризику, безпечніший шлях виправлення та що перевірити після змін.
Швидкий перший сигнал
У фокусі завжди критичні сценарії, тому перший звіт уже допомагає продукту й розробці приймати рішення.
Потрібен такий самий формат QA-артефактів для вашого продукту?
Покажемо, як може виглядати QA-підтримка саме для вашої команди: з баг-репортами, ретестами, ризиками релізу й зрозумілою структурою звіту.