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

    14 · AI для QA

    Підтримка тестів і аналіз падінь

    Зміст

    Автотести пишуть один раз, а супроводжують роками. Реальний час AQA витікає не на написання нового тесту, а на розбір червоного прогону вранці: що впало, чому впало, це баг продукту чи наш тест просто відстав від інтерфейсу. Саме тут AI спокушає найсильніше — кинути йому лог і спитати «що не так» здається способом зекономити годину тріажу. Іноді так і є. А іноді модель упевнено назве неправильну причину, ви полагодите не те, і червоне повернеться завтра.

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

    Тріаж фейлу: артефакти як контекст для AI

    Тріаж (triage) — це первинне сортування червоних тестів: швидко зрозуміти, що впало і куди копати. Головний принцип роботи з AI тут: діагноз рівно настільки хороший, наскільки повний контекст. Модель не має доступу до вашого CI, не бачить екрана, не знає стану бекенду. Усе, що вона «знає» про падіння, — це те, що ви вставили в промпт. Кинути голе Timeout 30000ms exceeded — те саме, що попросити лікаря поставити діагноз за одним словом «болить».

    Що реально несе інформацію про падіння:

    АртефактЩо з нього видно
    Повідомлення помилки + стек-трейсЯкий рядок і який виклик впав, тип помилки
    Локатор, що не зматчивсяЧого саме тест не знайшов на сторінці
    Скриншот на момент падінняЩо реально було на екрані: не той стан, помилка, порожнеча
    Trace / відео прогонуПослідовність дій, мережа, консоль, DOM-снапшоти по кроках
    Мережеві запити (HAR)Чи прийшов бекенд-виклик, який статус, що в тілі
    Логи застосункуПомилки сервера, correlation id, виняток на бекенді

    У Playwright майже все це збирається автоматично у trace-архів (опція trace: 'on-first-retry' записує трейс лише для повторного прогону впалого тесту). Trace viewer дає снапшот DOM на кожному кроці, мережу й консоль — це найбагатший контекст, який можна віддати AI для розбору (детальніше про сам trace viewer — у розділі про інструменти автоматизації). Ключове: згодовуйте AI факти прогону, а не свій переказ. Ваш переказ уже містить вашу гіпотезу, і модель радо на неї «приякорюється».

    Підтверджено

    Ні

    Червоний тест

    Зібрати артефакти:
    помилка, стек, скриншот, trace, мережа

    Дати AI факти прогону,
    не власний переказ

    AI пропонує гіпотези

    Перевірити гіпотезу
    руками / повторним прогоном

    Класифікувати: баг / тест / інфра

    Підтверджено

    Ні

    Червоний тест

    Зібрати артефакти:
    помилка, стек, скриншот, trace, мережа

    Дати AI факти прогону,
    не власний переказ

    AI пропонує гіпотези

    Перевірити гіпотезу
    руками / повторним прогоном

    Класифікувати: баг / тест / інфра

    Фейл ≠ баг: де AI помиляється в діагнозі

    Найважливіша ідея всього супроводу: падіння тесту не дорівнює баг застосунку. Червоний прогон має рівно три причини, і плутати їх дорого:

    1. Баг продукту — застосунок справді працює неправильно. Це те, заради чого тест існує.
    2. Баг тесту — крихкий локатор, забутий await, гонка в самому тесті, застарілий крок після зміни UI. Продукт здоровий.
    3. Інфраструктура / флак — оточення моргнуло, впав сусідній сервіс, тест-дані зайняв інший воркер.

    Ця класифікація — канон флакі-тестів (розділ «Автоматизація: стратегія», глава про флакі) і наскрізна тема співбесід; браузерну механіку того, чому UI-тест бачить «не той» стан, розібрано в главі Практичні сценарії AQA: флак і синхронізація.

    Тепер про те, як саме AI тут помиляється. Модель дає найправдоподібніший діагноз, а не найправильніший, і в неї є впізнавані патерни хиб:

    • Приякорення до симптому. Бачить Timeout — радить збільшити таймаут. Але таймаут спливає і коли елемента немає через реальний баг, і коли тест чекає не на те. «Збільш таймаут» замасковує гонку замість полагодити її.
    • Звинувачення застосунку за замовчуванням. AI охоче пише «схоже, у застосунку баг», бо це правдоподібна фраза — навіть коли винен крихкий тест. Для QA це найдорожча помилка: завести баг на здоровий продукт означає спалити довіру команди.
    • Вигаданий root cause, що пасує до симптому. Модель сконструює зв'язну причинну історію, яка ідеально пояснює лог і при цьому не має нічого спільного з реальністю. Гладкість тексту не корелює з правильністю — це та сама пастка, що й у главі Верифікація результатів AI.

    Практичне правило: AI генерує гіпотези, підтверджуєте їх ви — повторним прогоном, ручним відтворенням кроку, зазиранням у мережу чи БД. Гіпотеза «це баг бекенду» коштує один запит curl для перевірки; не перевіряти її й одразу заводити дефект — антипатерн.

    Флакі: аналіз патернів

    Ось де AI приносить найбільше чесної користі. Один флакі-фейл людина розбере й сама. А от патерн у сотні прогонів око не бачить — і саме тут модель сильна: згодуйте їй історію падінь (які тести, коли, на яких воркерах, у якому оточенні), і попросіть згрупувати за спільними ознаками.

    Типові патерни, які так виринають:

    • тест червоніє лише вночі → майже завжди таймзона чи межа доби в даних;
    • падає лише на воркері N при паралельному запуску → спільні тест-дані, конфлікт за одним акаунтом;
    • зелений локально, червоний лише в CI → headless-таймінги, повільніше оточення, інший стан кешу (див. Кешування);
    • серія тестів валиться після одного конкретного → протікання стану, порушена ізоляція.

    Чому це працює: LLM добре підсумовує й кластеризує накидані дані. Але межу треба тримати чітко: AI групує симптоми, а не встановлює причину. «Ці п'ять тестів падають на воркері 3» — це кластер, а не діагноз; чому саме воркер 3, з'ясовуєте ви. Модель дає напрямок пошуку й економить години читання логів — не готовий вирок.

    Рефакторинг тестів з AI

    Супровід — це ще й переписування старого коду, і тут AI сильний, бо більшість рефакторингу — механічні трансформації, які легко перевірити прогоном і diff-ом. Витягнути повторюваний блок у page object, прибрати дублювання, перейменувати, замінити застарілий патерн на сучасний — усе це модель робить швидко й здебільшого коректно.

    Класичний приклад — масова заміна хардкодних очікувань на web-first асерти:

    // Було: хардвейт — антипатерн, тримає флак і гальмує прогін
    await page.waitForTimeout(3000);
    expect(await page.locator('.status').textContent()).toBe('Готово');
    
    // Стало: web-first асерт з авторетраєм, чекає рівно скільки треба
    await expect(page.locator('.status')).toHaveText('Готово');

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

    Self-healing локатори і їхні ризики

    Self-healing локатори (самовідновні локатори) — це механізм, коли тестовий інструмент, не знайшовши елемент за основним селектором, не падає одразу, а намагається знайти «той самий» елемент за іншими ознаками (текст, ARIA-роль, сусідні вузли, позиція) і продовжити прогін. Це фіча низки комерційних платформ (Testim, Mabl, testRigor) і опенсорсних надбудов (Healenium для Selenium); у Playwright «з коробки» такого немає — там ставку зроблено на стабільні локатори за замовчуванням.

    Спокуса зрозуміла: після кожної зміни верстки менше червоних білдів, менше ручної правки локаторів. Але для QA тут ховається концептуальний конфлікт, і його треба вміти сформулювати на співбесіді:

    Сенс тесту — впасти, коли застосунок несподівано змінився. Self-healing прямо цьому протидіє. Якщо кнопку «Оплатити» перейменували на «Купити», це могло бути свідоме рішення продукту — а могла бути й регресія. Самовідновлення тихо «підлікує» локатор і зробить білд зеленим в обох випадках, і другий — це пропущений баг під виглядом успіху.

    Конкретні ризики:

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

    Здорова позиція: self-healing прийнятний як підказка для людини («локатор ось-ось зламається, ось кандидат на заміну — підтвердь»), а не як тихе автопродовження зеленим. Фундамент усе одно той самий, що й без AI — стабільні локатори (data-testid, ARIA-ролі) як контракт із розробкою; це канон стратегії локаторів у розділі автоматизації, а механіку селекторів розібрано в главі DOM, селектори та події.

    Оновлення тестів після зміни UI/API

    Коли фіча свідомо змінилася, десятки тестів червоніють законно — їх треба привести у відповідність. AI тут прискорює, але за однієї умови: давайте йому diff зміни, а не змушуйте вгадувати. Модель не бачила ні старого, ні нового застосунку; здогад «як тепер виглядає форма» — це вигадка. А от diff PR-у застосунку, зміна в OpenAPI-специфікації чи DOM «до/після» — це факти, з якими вона працює предметно.

    • Зміна API. Згодуйте diff OpenAPI або приклад нової відповіді — і модель оновить асерти на тіло, статуси, назви полів. Тут доречні контрактні перевірки схемою (валідація структури програмно), а не звірка полів очима.
    • Зміна UI. Новий data-testid, переміщений елемент, перейменована дія — з diff-ом розмітки AI оновить локатори й кроки швидко.

    Але є критична пастка, за яку карають на співбесіді. AI з радістю «полагодить» тест так, щоб він проходив під новий стан застосунку — навіть якщо цей стан і є регресією. Оновити впалий тест, щоб він позеленів, і закрити тікет — найлегший шлях зробити баг невидимим. Рішення «нова поведінка правильна» чи «це баг» — не технічне й не для моделі; його ухвалює людина за вимогами. AI прибирає механічну рутину оновлення; питання інтенту лишається за вами.

    AI-рев'ю в пул-реквесті

    AI-рев'ю (від вбудованого в термінальний агент до ботів, що коментують пул-реквести) працює у двох напрямках: рев'ю вашого тестового PR і рев'ю продуктового PR з погляду QA. У супроводі корисні обидва.

    Що AI ловить добре — це механічні дефекти й запахи, які око проскакує на великому diff:

    • забутий await перед web-first асертом;
    • тавтологічні перевірки на кшталт expect(true).toBeTruthy();
    • хардвейти замість авторетраю;
    • крихкі локатори за згенерованими класами;
    • відсутність негативних сценаріїв там, де вони очевидні.

    Чого AI не ловить — і чому він не заміняє людину-рев'юера: чи перевіряє тест правильний інваріант, чи відповідає очікуваний результат реальній вимозі, чи має зміна доменний сенс. Модель бачить форму коду, не його намір. Тому найнебезпечніший результат — зелене AI-рев'ю сприймають як гарантію якості: бот не знайшов зауважень, отже все добре. Ні: відсутність механічних зауважень не означає, що тести перевіряють те, що треба. AI-рев'ю — це швидкий перший фільтр, який знімає рутину з людини-рев'юера, а не gate, що її замінює; фінальне слово на PR лишається за інженером (інтеграцію таких перевірок у пайплайн розібрано в розділі про Git і CI/CD).

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

    • AI сказав «це баг застосунку» — виглядає як готовий діагноз, а насправді модель за замовчуванням звинувачує продукт; часто винен крихкий тест або флак, і перевірити треба руками до заведення дефекту.
    • Timeout → «збільш таймаут» — виглядає як фікс, а насправді таймаут маскує гонку чи реальну відсутність елемента; більший таймаут лише повільніше валиться.
    • Self-healing зробив білд зеленим — виглядає як стабільність, а насправді тест міг «загоїтися» на неправильний елемент або приховати регресію; сенс тесту — впасти на несподівану зміну.
    • AI оновив упалий тест, він проходить — виглядає як приведення у відповідність, а насправді тест міг бути підігнаний під баг; правильність нової поведінки вирішують вимоги, не модель.
    • Зелене AI-рев'ю в PR — виглядає як знак якості, а насправді бот перевіряє форму, а не те, чи тест ловить правильний інваріант.
    • Кинув голий лог, отримав причину — виглядає як тріаж, а насправді без trace/скриншота/мережі це вгадування; діагноз рівно такий, як контекст.

    Підсумок

    • AI у тріажі корисний рівно настільки, наскільки повний контекст: давайте йому артефакти прогону (trace, скриншот, мережу, стек), а не власний переказ із уже вбудованою гіпотезою.
    • Червоний тест — це три різні речі: баг продукту, баг тесту, інфраструктура/флак. AI генерує гіпотезу; класифікацію підтверджуєте ви.
    • Модель схильна приякорюватися до симптому, звинувачувати застосунок і вигадувати зв'язний, але хибний root cause — гладкість діагнозу не є його правильністю.
    • Self-healing локатори борються з самою метою тесту — падати на несподівану зміну; прийнятні як підказка людині, не як тихе автозагоєння зеленим.
    • AI прибирає механічну рутину рефакторингу, оновлення й рев'ю, але рішення про інтент («нова поведінка правильна чи це баг») і фінальний gate лишаються за інженером.

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

    • «Тест упав. Як ви користуєтесь AI, щоб розібратися?» — інтерв'юер хоче почути про збір контексту (trace, скриншот, мережа, логи), а не «кидаю лог — він каже причину». Сильна відповідь згадує, що AI дає гіпотезу, яку ви перевіряєте.
    • «AI сказав, що це баг застосунку. Що робите далі?» — пастка на різницю фейл ≠ баг. Правильно: не заводжу дефект наосліп, спершу відтворюю руками / перевіряю бекенд, класифікую баг тесту vs баг продукту vs флак.
    • «Що думаєте про self-healing локатори?» — перевірка зрілості. Очікують названий конфлікт: самовідновлення суперечить меті тесту падати на зміну; ризик маскування регресій і загоєння на не той елемент; прийнятно лише як підказка.
    • «AI переписав/оновив тест, він зелений. Мержимо?» — перевірка на автоматизаційне упередження. Сильна відповідь: спершу переконуюся, що тест червоніє при зламаній фічі, і що оновлення не підігнане під регресію.
    • «Чи можна довіряти AI-рев'ю в PR замість людини?» — очікують межу: AI ловить механічні дефекти й запахи, але не доменну коректність та інваріант; це фільтр, не gate.

    На що дивиться інтерв'юер: чи трактуєте ви AI-діагноз як гіпотезу на перевірку, а не як вирок; чи тримаєте різницю «фейл тесту ≠ баг продукту»; чи усвідомлюєте, що зелене (загоєний локатор, оновлений тест, чисте AI-рев'ю) не дорівнює правильному.

    Джерела

    • ISTQB Certified Tester Foundation Level (CTFL) v4.0 — базові поняття: різниця помилка/дефект/збій, хибнопозитивні та хибнонегативні результати тестів — теоретичне підґрунтя принципу «фейл ≠ баг».
    • ISTQB Certified Tester AI Testing (CT-AI) — охоплює як тестування AI-систем, так і використання AI в самому тестуванні; корисний для розуміння меж і ризиків AI-інструментів у супроводі.
    • Playwright — Trace Viewer — офіційна документація про trace як найбагатший артефакт падіння: дії, DOM-снапшоти, мережа, консоль.
    • Playwright — Best Practices — чому web-first асерти й стабільні локатори, а waitForTimeout — антипатерн; фундамент для рефакторингу супроводу.