Непрочные тесты

Нестабильный» тест - это тест, который демонстрирует периодические или спорадические сбои, который, похоже, имеет недетерминированное поведение. Иногда он проходит, иногда проваливается, и неясно, почему. На этой странице обсуждаются функции pytest, которые могут помочь, и другие общие стратегии для выявления, устранения или смягчения этих проблем.

Почему некачественные тесты - это проблема

Непрочные тесты особенно неприятны, когда используется сервер непрерывной интеграции (CI), так что все тесты должны пройти до того, как новое изменение кода будет слито. Если результат теста не является надежным сигналом - провал теста означает, что изменение кода нарушило тест - разработчики могут стать недоверчивыми к результатам тестирования, что может привести к игнорированию настоящих сбоев. Это также источник потерянного времени, поскольку разработчики должны повторно запускать наборы тестов и исследовать ложные сбои.

Потенциальные первопричины

Состояние системы

В широком смысле, нестабильный тест указывает на то, что тест полагается на некоторое состояние системы, которое не контролируется должным образом - тестовая среда недостаточно изолирована. Тесты более высокого уровня с большей вероятностью будут нестабильными, поскольку они полагаются на большее количество состояний.

При параллельном запуске набора тестов (например, при использовании pytest-xdist) иногда появляются нестабильные тесты. Это может указывать на то, что тест зависит от упорядочивания тестов.

  • Возможно, другой тест не справляется с самоочисткой и оставляет после себя данные, которые приводят к сбою неработающего теста.

  • Сбойный тест зависит от данных предыдущего теста, который не убирает за собой, а в параллельных запусках этот предыдущий тест не всегда присутствует.

  • Тесты, изменяющие глобальное состояние, обычно не могут выполняться параллельно.

Чрезмерно строгое утверждение

Слишком строгие утверждения могут вызвать проблемы со сравнением с плавающей запятой, а также проблемы с синхронизацией. Здесь полезно использовать pytest.approx().

Особенности Pytest

Строгость Xfail

pytest.mark.xfail с strict=False можно использовать для пометки теста так, чтобы его отказ не привел к поломке всей сборки. Это можно рассматривать как ручной карантин, и его довольно опасно использовать постоянно.

PYTEST_CURRENT_TEST

PYTEST_CURRENT_TEST может быть полезен для выяснения того, «какой тест застрял». См. раздел PYTEST_CURRENT_TEST переменная окружения для более подробной информации.

Плагины

Повторный запуск всех неудачных тестов может смягчить негативные последствия нестабильных тестов, дав им дополнительные шансы пройти, чтобы сборка в целом не потерпела неудачу. Несколько плагинов pytest поддерживают это:

Плагины для намеренной рандомизации тестов могут помочь выявить тесты с проблемами состояния:

Другие общие стратегии

Разделение наборов тестов

Часто можно разделить один набор тестов на два, например, модульный и интеграционный, и использовать только набор модульных тестов в качестве CI-гейта. Это также помогает поддерживать время сборки на приемлемом уровне, поскольку высокоуровневые тесты обычно работают медленнее. Однако это означает, что код, нарушающий сборку, может быть объединен, поэтому требуется повышенная бдительность для контроля результатов интеграционных тестов.

Видео/скриншот при неудаче

Для тестов пользовательского интерфейса они важны для понимания того, в каком состоянии находился пользовательский интерфейс, когда тест не прошел. pytest-splinter может использоваться с такими плагинами, как pytest-bdd, и может save a screenshot on test failure, что может помочь изолировать причину.

Удалить или переписать тест

Если функциональность покрывается другими тестами, возможно, тест можно убрать. Если нет, возможно, его можно переписать на более низком уровне, что устранит «шелушение» или сделает его источник более очевидным.

Карантин

Марк Лапьер обсуждает Pros and Cons of Quarantined Tests в посте от 2018 года.

Инструменты CI, которые повторно запускаются при сбое

Azure Pipelines (инструмент CI/CD в облаке Azure, бывший Visual Studio Team Services или VSTS) имеет функцию identify flaky tests и повторного запуска неудачных тестов.

Исследование

Это ограниченный список, пожалуйста, отправьте проблему или запрос на расширение!

  • Гао, Зебао, Ялан Лян, Майра Б. Коэн, Атиф М. Мемон и Чжен Ванг. «Обеспечение воспроизводимости интерактивных тестов пользователя системы: Когда и что мы должны контролировать?». In Software Engineering (ICSE), 2015 IEEE/ACM 37th IEEE International Conference on, vol. 1, pp. 55-65. IEEE, 2015. PDF

  • Паломба, Фабио и Энди Зайдман. «Провоцирует ли рефакторинг тестовых запахов исправление «шелушащихся» тестов?». In Software Maintenance and Evolution (ICSME), 2017 IEEE International Conference on, pp. 1-12. IEEE, 2017. PDF in Google Drive

  • Белл, Джонатан, Оволаби Легунсен, Майкл Хилтон, Ламьяа Элусси, Тифани Юнг и Дарко Маринов. «DeFlaker: Automatically detecting flaky tests.» In Proceedings of the 2018 International Conference on Software Engineering. 2018. PDF

Ресурсы

Вернуться на верх