Флейки-тесты, они же “флаки”, они же нестабильные, они же ненадежные, они же “моргающие”, они же “случайно успешные”
Flaky-тест, буквально “хлопчатый”, “рассыпающийся на кусочки”, в индустрии ИТ-тестирования означает нестабильный, ненадежный тест, который иногда “pass”, иногда “fail”, и трудно понять, по какой закономерности. Убийца времени тестировщика, источник нервозности в команде.
На такие тесты тратится много времени. Возникает задержка, пока команда не разберется, в чем дело. Конечно, страдает продуктивность.
Причины кратко
- Тестовый фреймворк изначально плохо собран. Его код не проверен на соответствие задачам. Совет: код фреймворка должен быть в достаточной мере чистым; должны соблюдаться принципы DRY, использоваться Object design pattern страницы, или Factory design pattern.
- В тесте слишком много hardcoded-данных. Нестабильность результатов тестов возникает, когда эти тесты запускаются в другом окружении. Надо откорректировать hardcoded-данные (практика показывает, что это чаще всего неправильно прописанные пути к чему-то, неправильные IP-адреса и т.п.).
- Кэширование предыдущего состояния теста и запуск нового теста с кэшированными данными. Лучше чистить кэш для каждого выполнения тестов. Проверяй данные перед каждым тестом, и очищай их состояние после каждого теста.
- По внешней причине, не связанной с самими тестами. Плохое подключение к интернету или к конкретной базе данных; неподходящая версия браузера; утечки памяти.
- “Потеря связи” со сторонним (3rd party) компонентом также приводит к ненадежности; здесь поможет тщательная проверка сторонних компонентов перед запуском.
- Неэффективные селекторы элементов (например XPATH), или некорректные координаты элементов. Селекторы можно поменять достаточно легко, корректируя дизайн страницы. Рекомендуется работать с более надежными селекторами (например “id” или “name”).
- Злоупотребление “sleep”-командами, останавливающими выполнение в ожидании чего-то. Здесь помогает замена “sleep”-ожидания на более надежное в этом плане “wait”-ожидание (пока элемент появится). Это экономит время и (почти) устраняет “моргание” тестов во многих случаях.
Что делать
Если есть время, надо документировать такие тесты, и отправлять в “карантин”. После выполнения тестов, проверь выведенные данные. Проверь логи, дампы памяти, текущее состояние системы. Возможно скриншоты, если это UI-тесты. В 90% случаев причина выяснится уже на этом этапе! Если нет, создай тикеты насчет этих тестов, и проверь их по одному в карантине, тщательно. Исключи тесты в карантине из пайплайна до конца проверки, пока не добьешься стабильности. В Google тоже бывают flaky-тесты, говорит Hala Samir из Google; как они решают эту проблему? Стандартно, например анализируют выведенные данные, проверяя корреляцию с функциями возможно вызвавшими нестабильность, по возможности без перезапуска тестов.
Еще раз о причинах
Если разделить причины по происхождению:
- Тесты сами по себе имеют “склонность к нестабильности”
- Проблемы с фреймворком
- Проблемы в подключаемых библиотеках/сервисах
- Проблемы в операционной системе / в устройстве
Подробнее.
Как уже говорилось выше, нестабильность результатов часто возникает из-за неправильной инициализации, или «очистки». Реже, но тоже случается - от неправильно подобранных тестовых данных. Головная боль тестировщиков - асинхронные действия, на это следует обращать особое внимание. Более простая причина - неправильный порядок запуска тестов.
Проблемы с фреймворком: часто фреймворк не сконфигурирован на выделение достаточных системных ресурсов; или неправильно планирует очередность запуска тестов, из-за чего они “перекрываются” между собой.
Если в проекте много сторонних библиотек или подключаемых сервисов, у них может быть свое “дерево зависимостей”, где и таятся причины нестабильности. Например переменные некорректно инициализируются; память “утекает”; какой-то ресурс не отвечает на запрос; и т.п. Чтобы исключить эти проблемы, в идеале надо стремиться к “герметичности” тестовой среды, то есть тестовая среда не должна иметь внешних зависимостей.
Операционная система и тестовые устройства. Банально, но причиной иногда бывает нестабильное интернет-подключение. Также банальная причина - ошибки чтения/записи на физический носитель данных.
Статистика
Статистически (со слов тестировщиков), основные причины нестабильности это: на первом месте по «сложности разбора» асинхронные операции (async wait); затем многопоточные операции; затем неправильный порядок запуска тестов; затем аппаратные проблемы (с сетью и синхронизацией времени, или с памятью).
Ну, а если найти причину нестабильных тестов и исправить их - не получается никак, то, как говорил вице-президент Unity3D Алан Берд, “нестабильные тесты это еще хуже, чем вообще без тестов”.
Источники:
Доп. материал: