К основному контенту

Flaky тесты (они же моргающие или "случайно успешные")

Недавно поучаствовал в Heisenbug Piter 2021 в роли эксперта на очередной серии доклада Андрея Солнцева про flaky тесты.

Люблю эту тему. Кажется, это своего рода "дебаг", только для тестов. Иногда расследование похлеще приключений Шерлока.

Тема flaky тестов древняя, как сама отрасль. Первое найденное упоминание термина в традиционных интернетах (типа блогов, твиттеров) в 2008 году в блоге гугла. Мне больше нравится называть их “моргающие” или, что четче отражает проблему, случайно успешные.

Давайте еще раз зафиксируем то, что поможет меньше попадать в историю, когда тесты у нас "случайно успешные" и что делать, если уже "вляпались".

Итак, что делать, чтобы "моргающих" тестов было меньше:

  • тесты должны быть написаны в правильном слое "той самой пирамиды": чем ближе слой к модульным тестам (а лучше именно в них), тем меньше шансов на моргания, потому что зависимостей меньше.
  • в ту же тему: чем меньше UI-тестов, тем лучше. Открывая в очередной раз файл с UI-тестами, помни, что тестировать надо "UI", а не "через UI".
  • основные причины "моргания" это асинхронные операции (async wait), многопоточность (concurrency), порядок тестов, утечка ресурсов, проблемы с зависимостями (сеть, время). Поэтому, чем меньше этого в тестах, тем они стабильнее.
  • основной объем бизнес-логики проверяем максимально близко к месту логики (см.пункт про слои) и с максимальным количеством замокированных зависимостей (но не переусердствуйте, а то будут другие проблемы)
К сожалению, полностью избавиться от flaky тестов сложно (окружение, сложные сценарии, много зависимостей), а местами просто дорого (по времени и ресурсам).

Что делать, если они появились?
  • разбирайтесь с проблемой падения максимально быстро. Не надо держать в наборе запускаемых тестов тот, доверия к результатам которого нет.
  • если сейчас нет возможности разобраться с ошибкой, переместите этот тест в "карантин", чтобы позже с ним разобраться. Не надо держать в наборе запускаемых тестов тот, доверия к результатам которого нет - 2.
  • если вы тестировщик, смотрите код тестируемого приложения. Часто проблемы с "морганиям" проще понять и поправить именно там. По статистике (2014 год) до 25% исправлений моргающих тестов делается в продакшен коде приложения.
  • привлекайте разработчиков, если сами не можете разобраться в коде.
  • активно используйте трейсинг (логирование) в тестах и продакшен-коде для того, чтобы воспользоваться ими при расследовании. Совет: здорово, если у вас есть возможность "объединить" логи тестируемой системы с логами тестов. Мы активно использовали запись меток о начале/завершении теста в продакшен логах приложения. Очень помогало.
  • для UI-тестов (помните про "через UI"?) имейте возможность включить запись видео или скриншоты в момент проверки
  • попробуйте переместить моргающую проверку на другой слой пирамидки
  • если тест не поддается и продолжает моргать, подумайте, может стоит его удалить? Все равно смысла от него немного, особенно если думать про него не "случайно упавший", а "случайно успешный". Ну и в целом "Flaky tests are worse than _no_ tests".
  • иногда советуют перезапускать упавшие тесты в надежде на удачу. В целом рабочий способ, но не надо им злоупотреблять. Он хорошо помогает с подтверждением проблемы и поиском test war. Но обнаруженные проблемы, например, с медленной инфраструктурой/сетью, особенностями фреймворков важно всегда фиксировать и планировать время на исправление.

Полезные ссылки:

Комментарии

Популярные сообщения из этого блога

Mock vs Stub

Когда мы начали изучать модульное тестирование, то одними из первых терминов, с которыми пришлось познакомиться, стали Mock и Stub. Ниже попробуем порассуждать в чем их сходство и различие, как и для чего они применяются. Проверять работоспособность тестируемого объекта (system under test - SUT) можно двумя способами: оценивая состояние объекта или его поведение. В первом случае проверка правильности работы метода SUT заключается в оценке состояния самого SUT, а также взаимодействующих объектов, после вызова этого метода. Во-втором, мы проверяем набор и порядок действий (вызовов методов взаимодействующих объектов, других методов SUT), которое должен совершить метод SUT. Собственно, если коротко, то в одном случае используется Stub, а в другом Mock. Это объекты, которые создаются и используются взамен реальных объектов, с которым взаимодействует SUT в процессе своей работы. Теперь подробнее. Gerard Meszaros использует термин Test Double (дублер), как обозначение для объе

Заметки на коленке - 3. Что еще делать, если ваши тесты уже "зеленые"?

"Lately I find I'm working on automated tests that return non-binary results. Tests that neither pass nor fail" by  @noahsussman Отличная мысль, которую я ретвитил еще в 2016. Но давайте вместе подумаем, что за этим может скрываться? ( кстати, не знаю, что при этом думал Noah ) Ваши тесты прошли и прошли "успешно". Все хорошо или все же есть, куда еще посмотреть? Дальше то, что использовал я лично и то, что еще можно прикрутить дополнительно. Естественно все шаги ниже должны быть автоматизированны. 1. Контролируйте время выполнения тестов. Если набор проверок не меняется (а такое часто бывает, к сожалению), то рост времени выполнения может говорить о проблемах в продакшен коде (чаще всего) или проблемах с окружением. 2. Контроль за количеством выполняемых тестов. "Все зеленое" не значит, что сегодня выполняли те же Х тестов, что и вчера. Смешно(нет), но случается такое, что какие-то проверки "исчезают" из запуска из-за того, что у кого-то &qu

Полезные ресурсы для молодых (и не только) тестировщиков

сперто(с) Уже 3 месяца провожу собеседования тестировщиков (март 2016). Поначалу они просто  веселили - после 15-летнего опыта собеседования С++-разработчиков, общение с тестировщиками (чаще были "-цы") было чем-то экзотическим и забавным. Потом становилось все грустнее и грустнее, мимими закончилось. Началась печаль.