Что автоматизировать, а что оставить руками — и почему «автоматизируем всё» убивает suite
«Давайте автоматизируем всё» — фраза, которая звучит правильно, а через полгода превращается в красный suite, которому никто не верит. Тесты падают, дежурный по CI на автомате жмёт «retry», зелёное никого не радует, а красное никого не пугает. И вот тогда автоматизация из помощника становится статьёй расходов.
Расскажу, как я для себя развёл «что автоматизировать» и «что оставить руками» — и почему второй список не меньше первого.
Тест, который мы чинили полгода, а надо было удалить
Был у нас один E2E-тест, который падал примерно раз в неделю. Каждый раз по новой причине: то анимация не успела, то тестовые данные кто-то поменял, то сторонний сервис на стейдже моргнул. Мы его чинили, добавляли ожидания, ретраи — а он падал снова.
В какой-то момент я сел и спросил: а что он вообще проверяет? Оказалось — сценарий, который не менялся год и ломаться не собирался, и который к тому же покрыт юнит-тестами уровнем ниже. Мы удалили тест. И стало лучше: suite позеленел, доверие вернулось, время на «чинить флаки» освободилось. Вот это был первый урок — не каждый тест стоит того, чтобы жить.
Автотест стоит не «написать», а «содержать»
Главная ошибка в оценке — считать стоимость автотеста как «время на написание». На самом деле тест стоит написать + гонять + чинить — годами. Он тормозит каждый прогон CI, он ломается на рефакторингах, его надо обновлять при смене UI. Если суммарная поддержка дороже пользы, которую он приносит, — это не актив, это пассив. Автоматизация окупается на повторении: то, что прогоняется сто раз, — да; то, что проверяется однажды, — почти никогда.
Что я автоматизирую
Хорошие кандидаты сходятся в одной точке: стабильное, частое, дорогое руками и с детерминированным результатом.
- Регресс критичных путей — то, что нельзя сломать (логин, оплата, ключевой сценарий продукта).
- API-контракты и расчёты — детерминированный вход-выход, дёшево и стабильно проверять.
- Кросс-браузерный/кросс-девайсный смоук — руками душно, машине легко.
- Скучные повторяющиеся проверки, которые прогоняются на каждый билд.
Что оставляю руками (и это не слабость)
- Ранний UI, который переделывают каждый спринт — автоматизировать движущуюся мишень = переписывать тесты вместо работы.
- Одноразовые проверки — быстрее проверить руками, чем писать тест, который прогонишь один раз.
- Субъективное: «красиво/удобно/не режет глаз», анимации, тон текста — это глаз человека, а не assert.
- Редкий кейс с монструозным setup — если подготовка стоит день ради одного прогона, посчитайте, стоит ли.
- Исследовательское тестирование — автотест проверяет то, что ты уже придумал; новые баги находит человек.
Пирамида — это не догма, это калькулятор
Тест-пирамиду проще воспринимать не как «правильную форму», а как инструмент решения: чем выше уровень (E2E), тем дороже прогон и тем хрупче тест; чем ниже (unit/API), тем дешевле и стабильнее. Поэтому дефолт простой: если проверку можно сделать уровнем ниже — сделай её ниже. Нужно проверить расчёт скидки — это юнит, а не клик через весь чекаут. Классика темы — у Мартина Фаулера про Test Pyramid и в practical test pyramid; а почему не надо валить всё в E2E — в Google Testing Blog.
Флаки-тест хуже отсутствующего
Это, наверное, главное. Тест, который падает через раз, не просто бесполезен — он ядовит. Он приучает команду игнорировать красное. А как только на один флаки закрыли глаза, перестают верить всему suite, и настоящий баг проезжает мимо под общим «да оно всегда так падает».
Правило простое: флаки-тест либо чинишь, либо удаляешь. «Замьютить и забыть» — худший вариант, потому что он оставляет дыру в покрытии и тихо врёт, что всё покрыто. Хорошо разобрано у Фаулера про non-deterministic tests: недетерминированный тест теряет главное свойство теста — доверие.
Как не спорить с командой
Чтобы «автоматизировать или нет» не превращалось в вкусовщину, я держу критерий на бумаге, а не «по ощущениям». Стабильно ли? Часто ли гоняем? Дорого ли руками? Детерминирован ли результат? Можно ли проверить уровнем ниже? Когда критерий явный, спор «давай заавтоматизируем» решается за минуту, а не эмоциями.
Чек-лист «автоматизировать или нет»
- Проверка стабильна (не меняется каждый спринт)
- Прогоняется часто (регресс, каждый билд), а не один раз
- Руками дорого/долго/скучно повторять
- Результат детерминированный (нет «на глаз»)
- Нельзя ли проверить дешевле уровнем ниже (unit/API)
- Стоимость поддержки годами < пользы
- Setup адекватен ценности кейса
- Готов чинить флаки сразу, а не мьютить
- Субъективное/красоту/exploratory — оставил человеку
Если коротко
Автоматизация — это не «покрыть всё», это выбор, куда вложить дорогой и живущий годами ресурс. Хороший автотест-инженер не тот, кто пишет больше тестов, а тот, кто знает, какие тесты не писать. «Автоматизируем всё» звучит амбициозно, а на практике убивает доверие к suite. Лучше пятьдесят тестов, которым верят, чем пятьсот, на которые жмут retry.
Источники: Martin Fowler — Test Pyramid, The Practical Test Pyramid, Google Testing Blog — Just say no to more E2E tests, Martin Fowler — Eradicating non-determinism in tests.