Почему зелёный CI не гарантирует, что система работает
Кейс из QA automation: как миграция на TypeScript привела к скрытому удвоению тестов без единого падения в CI

CI зелёный.
Тесты проходят.
Pull request’ы мерджатся.
Но система уже сломана.
И самое опасное — это не видно ни в логах, ни в отчётах CI.
В большинстве команд CI воспринимается как индикатор здоровья системы:
зелёный CI → всё работает
красный CI → есть проблема
Это удобная модель. Но она не всегда верна.
Контекст кейса
После миграции проекта с JavaScript на TypeScript мы заметили странное поведение:
CI стал выполняться почти в 2 раза дольше
тесты не падали
ошибок не было
метрики оставались “нормальными”
На первый взгляд — ничего критичного.
Что происходило на самом деле
Playwright начал подхватывать одновременно два набора тестов:
.spec.js.spec.ts
В результате один и тот же тестовый набор запускался дважды.
Самое неприятное — CI не просто не показывал проблему. Он создавал иллюзию, что всё становится лучше: время выполнения росло постепенно, и это воспринималось как “нормальная деградация после миграции”.
Почему это было незаметно
Проблема усугублялась полным отсутствием сигналов:
CI оставался зелёным
тесты не фейлились
никаких warning’ов
никаких алертов
Единственный симптом — увеличение времени выполнения. Которое списали на “ну TypeScript, наверное тяжелее”.
Как проблема была обнаружена
Случайно. Ближе к завершению миграции, при удалении .js файлов, количество тестов внезапно сократилось примерно в два раза:
было ~240
стало ~120
До этого момента CI фактически выполнял двойную работу — без каких-либо признаков аномалии.
Root cause
Root cause оказался банальным — и именно поэтому его так долго не замечали.
В playwright.config.ts отсутствовал явный testMatch. Playwright по умолчанию подхватывает все файлы, соответствующие glob-паттерну — и .js, и .ts одновременно.
Фикс — одна строка:
testMatch: [‘**/*.spec.ts’]
Но чтобы до неё дойти, нужно было сначала понять, что вообще происходит.
Архитектурный вывод
Большинство проблем в тестовых системах не проявляются как падения.
Они проявляются как:
дублирование выполнения
скрытая деградация производительности
изменения в поведении runner’а без изменений в тестах
И у них нет алертов — потому что мы их не проектируем.
Например, в нашем случае проблему можно было бы поймать простым счётчиком discovered tests в CI.
Финальный вывод
CI — это не инструмент контроля качества системы. Это инструмент контроля того, что тесты не упали.
И если вы используете его как индикатор качества — вы просто получаете ложную уверенность быстрее.
CI отражает только одно: тесты выполнились без явных ошибок.
CI не отражает: тесты запустились правильно, в правильном количестве, с правильными предположениями об окружении.
Если система может быть “зелёной” и при этом работать некорректно — значит у вас есть статус выполнения, но нет наблюдаемости.
Как это выглядит в реальной системе
Именно этот кейс лёг в основу проекта, который я собирала как QA portfolio. В pipeline добавлен счётчик discovered tests: если количество отклоняется от ожидаемого, CI падает явно, а не молчит. Рядом — buggy branch с намеренно сломанной конфигурацией, чтобы можно было воспроизвести и починить самостоятельно.
Код и структура проекта: GitHub (https://github.com/Ariless/clinic-booking-api-tests)
Если собираешь QA портфолио или готовишься к техническому собеседованию — в Telegram-канале Тесты как система (https://t.me/qa_as_a_system) разбираю такие кейсы с кодом и объяснением: что показывать, как объяснять решения, какие находки работают на собеседовании.











