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

    06 · Автоматизація: стратегія

    Флакі-тести: причини, діагностика, лікування

    Зміст

    Уяви: ти нічого не змінив у коді, запускаєш той самий тест удруге — і замість червоного він раптом зелений. Або навпаки: локально сотня прогонів поспіль без єдиного збою, а в CI він падає раз на десять запусків. Це і є (flaky test) — тест, результат якого недетермінований (non-determinism): на одному й тому ж коді, на одному й тому ж він то проходить, то падає. Найгірше в ньому не сам збій, а те, що він отруює довіру до всієї : коли команда звикає, що червоне «саме мине після рестарту», вона перестає читати падіння — і разом із проґавлює справжню . -тест — це не дрібна незручність, а повільна корозія цінності автоматизації.

    Питання «що таке флакі-тест і як ти з ним борешся» одразу показує, чи людина реально жила з CI, чи лише писала тести локально. Ця глава — канонічний виклад флаку на сайті: інші глави (браузерна механіка очікувань у розділі «Веб», засобами інструмента, «локально проходить — у CI падає» в CI/CD, флак в API-тестах) дають свої дельти й посилаються сюди. Якщо читаєш перед співбесідою за 15 хвилин — обов'язковий мінімум це таксономія причин, діагностика і теза «фейл тесту ≠ баг продукту»; метрики й командну політику можна залишити на другий прохід.

    Що таке флакі-тест і чому він отруює сюїту

    Формально флакі-тест — це тест із ненульовою ймовірністю різного результату за фіксованих вхідних умов: той самий код застосунку, той самий код тесту, те саме оточення (хоча б номінально), а вердикт стрибає. Ключове слово — недетермінованість. Детермінований тест на незмінних входах завжди дає той самий вихід; флакі — ні.

    Чому один нестабільний тест — це непропорційно велика проблема:

    • Ерозія довіри. Щойно команда бачить, що червоне буває «несправжнім», спрацьовує ефект хлопчика, який кричав «вовки»: на кожне падіння реакція «та це знову флак, ретрай». У цій атмосфері справжній баг проходить непоміченим.
    • CI-гейт стає театром. Якщо merge розблоковують ретраєм до першого зеленого, гейт більше нічого не гарантує — він лише імітує контроль.
    • Дорогий шум. Кожен «фальшивий» червоний — це чийсь час на розбір: відкрити звіт, подивитися , зрозуміти, що знову те саме. Помножити на розмір сюїти й частоту прогонів — виходять людино-години на порожньому місці.

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

    Таксономія причин

    Ми групуємо джерела флаку в п'ять сімейств — це наше педагогічне перегрупування, а не вичерпний поділ. У джерел переліки інші: канонічна таксономія xUnit Patterns розкладає Erratic Test на Interacting Tests, Unrepeatable Test, Test Run War, Nondeterministic Test і Resource Leakage; у Фаулера теж п'ятірка, але своя — ізоляція, асинхронність, віддалені сервіси, час і витік ресурсів (останнього в нашому списку немає взагалі); Google називає причини відкритим списком із «etc.», тобто на повноту не претендує. Цінність нашої класифікації в іншому: вона і є алгоритм діагностики, бо кожне сімейство має свій характерний симптом і свій метод лікування.

    Час, момент готовності UI/даних

    Стан, який лишили інші тести/прогони

    Залежність від порядку виконання

    Ресурси, мережа, сторонні сервіси

    Сам застосунок недетермінований

    Тест недетермінований

    Що змінюється між прогонами?

    Синхронізація

    Дані

    Порядок і взаємозалежність

    Оточення й інфраструктура

    Баг продукту

    Час, момент готовності UI/даних

    Стан, який лишили інші тести/прогони

    Залежність від порядку виконання

    Ресурси, мережа, сторонні сервіси

    Сам застосунок недетермінований

    Тест недетермінований

    Що змінюється між прогонами?

    Синхронізація

    Дані

    Порядок і взаємозалежність

    Оточення й інфраструктура

    Баг продукту

    Синхронізація

    Найчастіша причина — і майже завжди перша підозра. Тест і застосунок працюють асинхронно: тест уже намагається клікнути кнопку, а вона ще не з'явилась; читає текст, який щойно оновлюється запитом; переходить далі, поки триває анімація. Результат залежить від того, хто встиг першим, а це — питання мілісекунд, які плавають від прогону до прогону.

    Класичний антипатерн — (hard wait): пауза на фіксовану кількість мілісекунд у надії, що «стільки точно вистачить».

    // Крихко: сподіваємось, що 2 секунди вистачить завжди
    await page.waitForTimeout(2000);
    await expect(page.getByRole('button', { name: 'Save' })).toBeVisible();
    
    // Надійно: web-first assertion сам чекає появи до таймауту
    await expect(page.getByRole('button', { name: 'Save' })).toBeVisible();

    Фіксована пауза програє в обидва боки: на швидкому прогоні вона просто гальмує сюїту, на повільному (навантажений CI-агент) — не дочікується й падає. Правильний інструмент — очікування за умовою: web-first assertions з , стану, очікування конкретної відповіді мережі. Механіку браузерних очікувань детально розбирає глава «Практичні сценарії AQA: флак і синхронізація»; автоочікування конкретно в Playwright — окрема глава розділу «Інструменти».

    Дані

    Тест залежить від стану, який він не контролює повністю. Типові прояви: два тести пишуть в одного й того ж користувача; дані з попереднього прогону не прибрані й ламають ; тест створює запис з неунікальним email і падає на дублікаті при повторі; перевірка спирається на «перший рядок таблиці», а порядок недетермінований.

    Окрема підступна категорія — час, дати й випадковість: тест, що падає лише опівночі або лише в певній таймзоні; перевірка «створено сьогодні», яка ламається на межі доби; Math.random() у . Лікування — ізоляція й детермінізм: унікальні дані на кожен тест, підготовка стану через API/БД, фіксація часу й . Стратегію тестових даних цілком розкриває канонічна глава про фабрики, фікстури та ізоляцію.

    Порядок і взаємозалежність тестів

    Тест зелений, коли йде п'ятим, і червоний, коли перший, — класична ознака залежності від порядку. Хтось лишив після себе стан (залогінена сесія, створений запис, змінена глобальна змінна), і наступний тест мовчки на нього спирається. Доки порядок стабільний, проблеми не видно; варто ввімкнути рандомізацію порядку або паралельний запуск — і сюїта розсипається.

    Це прямий наслідок порушення незалежності й атомарності, які розбирає глава «Анатомія автотесту». Паралелізм цю категорію загострює: два , що ділять один акаунт чи один рядок БД, влаштовують гонку за спільний ресурс — деталі в главі «Паралелізація». Швидкий тест на цю причину: запусти підозрілий тест ізольовано (--repeat-each) — якщо сам по собі він стабільний, винен не він, а сусіди або спільний стан.

    Оточення й інфраструктура

    Тест падає не через код, а через середовище, у якому виконується. Джерела: перевантажений CI-агент дає інші таймінги, ніж потужний ноутбук; «моргання» мережі; недоступний або повільний сторонній сервіс (платіжка, пошта, зовнішнє API); різниця headless проти headed; відсутні шрифти в Docker- ламають тести; таймзона чи локаль агента відрізняються від локальних; застаріла версія фронтенду з CDN або service worker (див. главу «Кешування»).

    Головний важіль тут — прибрати зовнішні залежності з-під ніг тесту: те, що нестабільне й не є об'єктом перевірки, підмінити дублером. Що і навіщо навіть в e2e — у главі «Тестові дублери». Окремий і дуже поширений підвид цієї категорії — «локально зелено, у CI червоно»; про нього нижче.

    Баг продукту (справжня недетермінованість)

    Найважливіша й найчастіше проґавлена категорія: тест флакає, бо застосунок справді поводиться недетерміновано. Реальна гонка (race condition) на бекенді, (eventual consistency), стан, що протікає між запитами користувача, — усе це нестабільність продукту, яку тест чесно ловить. Кінцева узгодженість тут варта окремого слова, бо це не крайній випадок, а режим за замовчуванням у реальних сховищах: дока DynamoDB пише, що відповідь на читання «may not reflect the results of a recently completed write operation», і що повторний запит через короткий час поверне свіжіші дані. Звідси корисний практичний хід: сильна узгодженість часто є опцією запиту, тож замість ретраїв іноді достатньо попросити її явно.

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

    Діагностика: відтворити, зібрати артефакти, локалізувати

    Діагностика флаку — це відповідь на два питання: чи це взагалі флак (а не стабільно відтворюваний баг) і до якого з п'яти сімейств він належить. Порядок дій:

    Так, завжди

    Ні, плаває

    Так

    Ні, лише в наборі

    Тест упав

    Відтворюється
    стабільно?

    Це не флак:
    баг тесту або продукту

    Зібрати артефакти:
    трейс, відео, логи, скрин

    Запустити локально
    в циклі: repeat-each

    Падає
    ізольовано?

    Синхронізація / дані /
    оточення / баг продукту

    Порядок і
    взаємозалежність

    Так, завжди

    Ні, плаває

    Так

    Ні, лише в наборі

    Тест упав

    Відтворюється
    стабільно?

    Це не флак:
    баг тесту або продукту

    Зібрати артефакти:
    трейс, відео, логи, скрин

    Запустити локально
    в циклі: repeat-each

    Падає
    ізольовано?

    Синхронізація / дані /
    оточення / баг продукту

    Порядок і
    взаємозалежність

    Артефакти — головне джерело істини. Флак майже неможливо зловити «дивлячись очима», бо він рідкісний. Тому інфраструктура має ловити його за тебе: трейс (trace) з покроковими знімками DOM, мережею й , відео падіння, скріншот у момент збою, серверні логи з correlation id. Розбір фейлу від звіту до першопричини — тема глави «Звітність»; тут важливо запам'ятати: без збережених артефактів флак недіагностовний, бо на повторному прогоні він уже зелений.

    Відтворення керованим повтором. Ручний повтор — ненадійний : пройшло тричі поспіль нічого не доводить. Треба ганяти тест сотнями ітерацій у циклі (--repeat-each у Playwright; в CodeceptJS чи інших — циклом або скриптом-обгорткою), бажано під навантаженням, що імітує CI (обмежити CPU, паралельні воркери). Якщо в ізоляції тест стабільний, а в повному наборі — ні, ти щойно локалізував причину як «порядок і взаємозалежність».

    «Локально зелено — у CI червоно»

    Окремий діагностичний сценарій, який плутає новачків: локально тест бездоганний, у CI регулярно падає. Це майже завжди категорія «оточення», і причини типові:

    • CI-агент слабший і навантаженіший — усе виконується повільніше, вилазять приховані гонки синхронізації, яких на швидкій машині просто не було часу побачити.
    • Headless-режим відрізняється від headed розмірами , доступними шрифтами, поведінкою деяких API.
    • Паралельність у CI вища — прокидаються конфлікти за спільні дані.
    • Чисте оточення: у CI немає твого залогіненого стану, кешу, локальних змінних середовища, які локально мовчки «допомагали» тесту.

    Практичний висновок: не «ретрай джоб, поки не позеленіє», а відтвори CI-умови локально (менше ресурсів, headless, паралель, чистий профіль). Детальніше CI-специфічні причини розбирає глава про стабільність автотестів у CI в розділі «Git і CI/CD».

    Ретраї: легітимні проти маскування

    Ретрай (retry) — автоматичний повторний прогін упалого тесту. Це найгостріша етична розвилка теми, бо ретрай одночасно й корисний інструмент, і найпопулярніший спосіб замести флак під килим.

    // playwright.config.ts — 2 ретраї лише в CI, локально нуль
    export default defineConfig({
      retries: process.env.CI ? 2 : 0,
    });

    Коли ретрай легітимний: як пом'якшення справді неусувних, рідкісних збоїв інфраструктури (моргання мережі до стороннього сервісу, який ти не контролюєш), поки команда рухається до кореневого фіксу. Ключова умова — ретрай не мовчить: кожен «passed on retry» логується як сигнал флаку, потрапляє в метрику й у на розбір. Ретрай тут — знеболювальне на час лікування, а не саме лікування.

    Коли ретрай — маскування: коли retries виставляють глобально й високо (умовні три-п'ять), щоб сюїта «просто була зеленою», і на цьому заспокоюються. Проблеми такого підходу: справжня недетермінованість продукту (той самий баг гонки) ховається за зеленим; час прогону росте (кожен флакі-тест іноді біжить двічі-тричі); флак накопичується, бо стимул його чинити зник. Правило: ретрай купує час, але не скасовує обов'язку знайти причину. Тест, який стабільно проходить лише з другої спроби, — не «майже зелений», а незафіксований дефект. Механіку ретраїв засобами інструмента (рівні конфігу, per-project) розбирає окрема глава розділу «Інструменти».

    Карантин

    Що робити з тестом, який флакає прямо зараз і блокує merge всій команді, а причину швидко не знайти? Відповідь — карантин (quarantine): тест позначають спеціальним тегом, виносять із блокувального гейта (він більше не «валить» PR), але продовжують ганяти й відстежувати.

    test('оновлення профілю', { tag: '@flaky' }, async ({ page }) => {
      // ...
    });

    Карантин розв'язує гострий конфлікт: один флакі-тест не має права зупиняти доставку всієї команди, але й тихо видаляти його не можна — він щось перевіряє. Критично важливо, щоб карантин не став цвинтарем: правильний карантин має власника, дедлайн і трекінг. Тег @flaky без тікета й відповідального — це просто спосіб назавжди перестати дивитися на тест. Жорсткіший варіант для зовсім занедбаних тестів — видалити тест, а не тримати його вічно зеленим через ретраї: мертвий тест, що нічого не гарантує, створює ілюзію . Але це наша позиція, і вона розходиться з каноном: xUnit Patterns називає тесту одним із двох шкідливих простих виходів, бо це свідома втрата покриття (другий такий вихід — лишити тест червоним, за яким перестають помічати нові падіння). Тож видаляти можна лише тоді, коли команда справді свідомо приймає цю втрату, а не ховає нею проблему.

    Так

    Ні

    Так

    Ні

    Тест флакає
    й блокує merge

    Причину видно
    швидко?

    Полагодити зараз

    Карантин: тег @flaky,
    прибрати з гейта

    Тікет: власник + дедлайн

    Полагоджено
    до дедлайну?

    Повернути в гейт

    Ескалація або видалення

    Так

    Ні

    Так

    Ні

    Тест флакає
    й блокує merge

    Причину видно
    швидко?

    Полагодити зараз

    Карантин: тег @flaky,
    прибрати з гейта

    Тікет: власник + дедлайн

    Полагоджено
    до дедлайну?

    Повернути в гейт

    Ескалація або видалення

    Метрики стабільності

    Флак не можна лікувати наосліп — потрібні цифри, інакше «здається, стало краще» ніхто не спростує. Корисні (та чесні) метрики:

    • Flaky rate — частка тестів (або прогонів), що дали різний результат за фіксованого коду. Найпряміший вимір здоров'я сюїти.
    • Passed on retry — скільки тестів проходять лише з ретраю. Це прямий детектор прихованого флаку: якщо тест позеленів після червоного без змін коду — він нестабільний за визначенням.
    • Розмір і вік карантину — скільки тестів у карантині й наскільки давно. Зростаючий тренд означає, що команда виносить швидше, ніж чинить.
    • Час до фіксу — скільки живе флакі-тікет від заведення до закриття.

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

    Політика команди

    Технічні прийоми не працюють без домовленостей. Здорова політика щодо флаку тримається на кількох рішеннях:

    • Ownership. У кожного червоного є хтось, хто відповідає за розбір — інакше «нічий» флак живе вічно. Хто чинить червоний і як розподілене володіння автотестами — тема глави «shift-left і ownership».
    • Флак як дефект, а не фон. Нестабільний тест заводиться як баг із пріоритетом, а не «колись подивимось». Один терпимий флак нормалізує наступний.
    • Правила гейта. Домовленість, що саме блокує merge і за яких умов тест іде в карантин, а не тихо ретраїться. Розкладка прогонів (smoke на PR, повна регресія nightly) і quality gates — канон розділу «Git і CI/CD».
    • Бюджет на стабільність. Свідомо виділений час на «прибирання» сюїти, бо флак накопичується сам, а розсмоктується — ні.

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

    • Виглядає як баг застосунку (тест червоний) — а насправді флак самого тесту: гонка синхронізації, брудні дані, залежність від порядку. Перше питання завжди: тест відтворюється стабільно чи плаває?
    • Виглядає як флакі-тест, який «просто крихкий», — а насправді справжня гонка в продукті, яку цей тест єдиний ловить. Заглушити його ретраєм — приховати реальний баг.
    • Виглядає як розв'язана проблема (сюїта зелена після retries: 3) — а насправді флак нікуди не дівся, лише сховався; час прогону виріс, стимул чинити зник.
    • Виглядає як доказ стабільності («ретраїв тричі — пройшло») — а насправді ручний повтор нічого не доводить: потрібні сотні ітерацій під CI-подібним навантаженням.
    • Виглядає як баг у коді тесту («локально ж працює») — а насправді різниця оточення: слабший агент, headless, вища паралель, чистий профіль без твого локального стану.
    • Виглядає як акуратне рішення (тег @flaky) — а насправді вічний карантин без власника й дедлайну, тобто тихе списання перевірки.

    Підсумок

    • Флакі-тест недетермінований: той самий код — різний вердикт. Небезпечний він не збоєм, а ерозією довіри до всієї сюїти й перетворенням CI-гейта на театр.
    • Причини ми групуємо в п'ять сімейств: синхронізація, дані, порядок/взаємозалежність, оточення, баг продукту. Це наше перегрупування, а не вичерпний поділ, зате воно і є алгоритм діагностики.
    • Фейл тесту ≠ баг продукту — але флак ≠ автоматично провина тесту. Перш ніж лікувати тест, виключи справжню недетермінованість застосунку.
    • Діагностика неможлива без артефактів (трейс/відео/логи) і керованого повтору; ручний «пройшло тричі» — не доказ.
    • Ретрай купує час, не скасовує фіксу; карантин має бути з власником і дедлайном, а не цвинтарем. Метрики (flaky rate, passed on retry) роблять прогрес видимим.

    Можливі питання

    • «Що таке флакі-тест і чому це проблема?» Очікують визначення через недетермінованість плюс головний наслідок — ерозію довіри й знецінення гейта, а не просто «тест іноді падає».
    • «Назви причини флаку» — інтерв'юер перевіряє, чи є в голові систематика. Сильна відповідь — п'ять сімейств із прикладом на кожне, а не хаотичний список «мережа, таймінги, ще щось».
    • «Тест зелений локально, червоний у CI — твої дії?» Дивляться, чи не скажеш «перезапущу джоб». Правильно: зібрати артефакти, відтворити CI-умови локально (менше ресурсів, headless, паралель, чистий профіль), локалізувати причину.
    • «Ретраї — це добре чи погано?» Перевірка на зрілість. Очікувана теза: легітимно як тимчасове знеболювальне з логуванням і беклогом; погано як глобальний спосіб зробити сюїту «зеленою» й заспокоїтись.
    • «Куди подіти флакі-тест прямо зараз?» Карантин із власником і дедлайном; згадка, що вічний карантин або мовчазний ретрай — антипатерн.

    Структура сильної відповіді (той самий скелет розбору й у реальному дебагу): уточни симптом → відтвори повтором і артефактами → віднеси до одного з п'яти сімейств → перевір, що це не баг продукту → тимчасово карантин/ретрай із трекінгом → кореневий фікс → закрий метрикою й командною домовленістю. Кандидат, який проходить цей ланцюг вголос, одразу читається як людина з реальним CI-досвідом.

    Джерела

    Що таке флакі-тест і чому він отруює сюїту

    • xUnit Test Patterns — Erratic Test — канонічне означення («give different results depending on when they are run and who is running them») і розбір двох «простих» виходів: прибрати тест = свідомо втрачений тест, лишити червоним = він затуляє інші падіння.
    • Google Testing Blog — Flaky Tests at Google — вужче, вимірювальне формулювання («a test that exhibits both a passing and a failing result with the same code») і механізм шкоди: звикання до хибних сигналів веде до ігнорування справжніх падінь (trust: secondary, dec-0710).

    Таксономія причин

    • xUnit Test Patterns — Erratic Test — канонічна пʼятірка поіменно: Interacting Tests, Unrepeatable Test, Test Run War (можлива тільки за глобально спільної ), Nondeterministic Test і Resource Leakage.
    • Martin Fowler — Eradicating Non-Determinism in Tests — інша пʼятірка, названа в главі: Lack of Isolation, Asynchronous Behavior, Remote Services, Time, Resource Leaks — рубрикація саме цієї статті, а не галузева таксономія (trust: secondary, dec-0311).
    • Selenium — Waiting Strategies — гонка з браузером названа прямо однією з головних причин флакі-тестів, і жорстка пауза програє двічі: замало — падає, забагато — прогін стає непідйомним.
    • Playwright — Best Practices — що ставлять замість паузи: web-first чекає й повторює перевірку, а expect(await locator.isVisible()).toBe(true) не чекає жодної секунди; там же — вимога повної ізоляції тесту як засіб проти сімейства «дані й порядок».
    • Cypress — Test Retries — перелік типових джерел нестабільності в іншого інструмента: , доступність сервера й БД, залежності від ресурсів, мережа.
    • AWS — DynamoDB read consistency — категорія «застосунок справді недетермінований» із конкретним механізмом: кінцева узгодженість за замовчуванням не гарантує, що запис буде видно одразу.
    • Google Testing Blog — Flaky Tests at Google — там причини подано відкритим списком із «etc.», тобто на повноту джерело не претендує (trust: secondary, dec-0710).

    Діагностика: відтворити, зібрати артефакти, локалізувати

    • xUnit Test Patterns — Erratic Test — канон вимагає не ретраїв, а систематичного збору даних у часі за чотирма осями (середовище, підмножина тестів, повтор поспіль, паралельні ранери); для витоків ресурсів названо конкретну тактику — звести пул до 1.
    • Jest — Setup and Teardown — перше діагностичне питання у формулюванні офіційної доки ранера: чи падає тест, коли він єдиний у прогоні.
    • Playwright — Trace viewer — інструмент post-mortem-розбору саме для падінь у CI: і тривалість кожної дії, DOM-знімки до й після, мережа й консоль.
    • ISTQB® CTAL-TAE Syllabus v2.0 — §6.1: у разі падіння рішення автоматизації має зберегти все, що потрібно для аналізу, включно з дампами й стеками.

    Ретраї: легітимні проти маскування

    • Playwright — Test retries — ранер розводить три стани, а не два: passed, flaky (упав з першого разу, пройшов на ретраї) і failed; тест ще й бачить, що він на ретраї (testInfo.retry), і може почистити серверний стан перед повтором.
    • Cypress — Test Retries — позиціювання самих інструментів: ретраї вимкнені за замовчуванням і потрібні, щоб флак виявити, а не сховати.
    • Playwright — Test configuration — типова конфігурація доки: ретраї лише в CI, локально нуль; трейс should записуватися на першому ретраї, тобто ретрай є ще й способом зібрати діагностику.
    • Google Testing Blog — Flaky Tests at Google — ціна маскування названа числом: схему «падати лише після трьох разів поспіль» джерело саме називає далеко не ідеальною, бо 15-хвилинний тест покаже поломку через 45 хвилин (trust: secondary, dec-0710).

    Карантин

    • Google Testing Blog — Flaky Tests at Google — карантин як третій вихід у практиці, що описана: інструмент стежить за рівнем флаку, за перевищення порогу саджає тест у карантин автоматично й заводить баг; там же чесно названа ціна — це може замаскувати справжню гонку (trust: secondary, dec-0710).
    • xUnit Test Patterns — Erratic Test — чому третій вихід взагалі потрібен: прибрати тест = свідомо втрачений тест, лишити червоним = затулити інші падіння.
    • ISTQB® CTAL-TAE Syllabus v2.0 — звідки беруться дані для рішення: за історією прогонів знаходять й вирішують, рефакторити їх чи переписувати.

    Метрики стабільності

    • Google Testing Blog — Flaky Tests at Google — числа подано як атрибутовану вимірку 2016 року, а не галузеву константу: 1,5 % прогонів дають флакі-результат, ~16 % тестів мають якийсь рівень флаку, 84 % переходів «зелений → червоний» — це флак; там же — темп появи флаку дорівнює темпу лагодження (trust: secondary, dec-0710).
    • Allure Report — History and retries — інструментальний бік метрики: історія прогонів і ретраїв, з якої тренд узагалі стає видимим.
    • ISTQB® CTAL-TAE Syllabus v2.0 — навіщо історія потрібна крім звіту: за нею знаходять крихкі (fragile) тести.

    Політика команди

    • Google Testing Blog — Flaky Tests at Google — підстава для політики, а не для гасла: темп появи флаку дорівнює темпу лагодження, тож ним керують, а не «виліковують остаточно»; механізм деградації довіри — звикання до хибних сигналів (trust: secondary, dec-0710).
    • ISTQB® CTAL-TAE Syllabus v2.0 — §6.1: окремий стан прогону «дефект не в SUT, а в самому рішенні автоматизації» і вимога дати станам чіткі й консистентні означення — це і є формалізована політика .

    Пояснення

    «Поясни» працює з власним API-ключем Anthropic: запит іде з вашого браузера прямо до Anthropic.

    Свій API-ключ (BYOK)

    Вставте власний ключ Anthropic — пояснення працюватиме на реальній моделі. Ключ зберігається лише у вашому браузері (localStorage), нікуди не надсилається, крім api.anthropic.com, і не логується.