Нестабильные тесты
«Нестабильный» тест — это тест, который периодически или время от времени завершается с ошибкой и демонстрирует недетерминированное поведение. Иногда он проходит, иногда завершается с ошибкой, и причина этого неясна. На этой странице рассматриваются возможности pytest, которые могут помочь, а также общие стратегии выявления, исправления и смягчения этой проблемы.
Почему нестабильные тесты — это проблема
Нестабильные тесты особенно проблематичны при использовании сервера непрерывной интеграции (CI), где все тесты должны пройти, прежде чем можно будет влить новое изменение кода. Если результат теста не является надёжным сигналом — то есть ошибка теста не означает, что изменение кода его сломало, — разработчики могут перестать доверять результатам тестирования, из-за чего настоящие ошибки могут остаться незамеченными. Кроме того, это приводит к потере времени: разработчикам приходится повторно запускать наборы тестов и разбираться в ложных ошибках.
Возможные первопричины
Состояние системы
В целом нестабильный тест указывает на то, что он зависит от некоторого состояния системы, которое не контролируется должным образом, — тестовая среда недостаточно изолирована. Тесты более высокого уровня чаще бывают нестабильными, поскольку зависят от большего количества состояний.
Нестабильные тесты иногда проявляются при параллельном запуске набора тестов (например, при использовании pytest-xdist). Это может указывать на зависимость теста от порядка выполнения.
- Возможно, другой тест не выполняет очистку после себя и оставляет данные, из-за которых нестабильный тест завершается с ошибкой.
- Нестабильный тест зависит от данных предыдущего теста, который не выполняет очистку после себя, а при параллельном запуске этот предыдущий тест присутствует не всегда.
- Тесты, изменяющие глобальное состояние, обычно нельзя запускать параллельно.
Чрезмерно строгие проверки
Чрезмерно строгие проверки могут создавать проблемы при сравнении чисел с плавающей точкой, а также вызывать ошибки, связанные со временем выполнения. В этом случае полезен pytest.approx().
Потокобезопасность
pytest работает в одном потоке: тесты всегда выполняются последовательно в одном и том же потоке, и сам pytest никогда не создаёт дополнительные потоки.
Даже плагины, запускающие тесты параллельно, например pytest-xdist, обычно создают несколько процессов и запускают тесты пакетами, не используя несколько потоков.
Разумеется, тесты и фикстуры могут (и часто так делают) создавать собственные потоки в рамках тестового процесса (например, фикстура может запускать серверный поток в фоновом режиме, а тест — выполнять производственный код, создающий потоки), однако при этом нужно соблюдать осторожность:
- Обязательно дожидайтесь завершения всех созданных потоков — например, в конце теста или при очистке фикстуры.
- Не используйте примитивы pytest (
pytest.warns(),pytest.raises()и т. д.) из нескольких потоков, поскольку они не являются потокобезопасными.
Если в вашем наборе тестов используются потоки и результаты тестов нестабильны, не исключайте вероятность того, что тест неявно использует глобальное состояние самого pytest.
Другие общие стратегии
Разделение наборов тестов
Часто один набор тестов разделяют на два, например на модульные и интеграционные тесты, и в качестве условия для прохождения CI используют только набор модульных тестов. Это также помогает поддерживать приемлемое время сборки, поскольку тесты более высокого уровня обычно выполняются медленнее. Однако в результате становится возможным влить изменение кода, приводящее к сбою сборки, поэтому результаты интеграционных тестов нужно отслеживать особенно тщательно.
Видео или снимок экрана при ошибке
Для тестов пользовательского интерфейса это важно, чтобы понять, в каком состоянии находился интерфейс при сбое теста. pytest-splinter можно использовать с такими плагинами, как pytest-bdd; он умеет сохранять снимок экрана при сбое теста, что помогает установить причину.
Удаление или переписывание теста
Если функциональность проверяется другими тестами, возможно, этот тест можно удалить. Если нет, возможно, его можно переписать на более низком уровне, что устранит нестабильность или сделает её источник более очевидным.
Изоляция
Марк Лапьер обсуждает преимущества и недостатки изолированных тестов в публикации 2018 года.
Инструменты CI, повторно запускающие тесты при сбое
В Azure Pipelines (облачном инструменте CI/CD Azure, ранее известном как Visual Studio Team Services или VSTS) есть функция для выявления нестабильных тестов и повторного запуска тестов, завершившихся с ошибкой.
Исследования
Этот список неполный. Чтобы дополнить его, отправьте сообщение о проблеме или запрос на включение изменений!
- Гао, Цзэбао, Ялань Лян, Майра Б. Коэн, Атиф М. Мемона и Чжэнь Ван. «Повторяемость интерактивных системных тестов: когда и что следует контролировать?». В сборнике Разработка программного обеспечения (ICSE), 37-я международная конференция IEEE/ACM по разработке программного обеспечения, 2015, т. 1, с. 55–65. IEEE, 2015. PDF
- Паломба, Фабио и Энди Зайдман. «Помогает ли рефакторинг тестовых антипаттернов исправлять нестабильные тесты?». В сборнике Сопровождение и развитие программного обеспечения (ICSME), международная конференция IEEE по сопровождению и развитию программного обеспечения, 2017, с. 1–12. IEEE, 2017. PDF на Google Диске
- Белл, Джонатан, Оволаби Легунсен, Майкл Хилтон, Ламьяа Элусси, Тиффани Юнг и Дарко Маринов. «DeFlaker: автоматическое выявление нестабильных тестов». В сборнике Материалы международной конференции по разработке программного обеспечения, 2018. 2018. PDF
- Датта, Сайкат, Ши Август, Чоудхари Рутвик, Чжан Чжекун, Джайн Арьяман и Мисайлович Саша. «Выявление нестабильных тестов в вероятностных приложениях и приложениях машинного обучения». В сборнике Материалы 29-го международного симпозиума ACM SIGSOFT по тестированию и анализу программного обеспечения (ISSTA), с. 211–224. ACM, 2020. PDF
- Хабчи, Сарра, Габен Хабен, Чонгджу Зон, Адриано Франчи, Майк Пападакис, Максим Корди и Ив Ле Траон. «Что сделало этот тест нестабильным? Определение классов, ответственных за нестабильность тестов». В сборнике материалов 38-й международной конференции IEEE по сопровождению и развитию программного обеспечения (ICSME), IEEE, 2022. PDF
- Лампру, Сократес. «Недетерминированные тесты и где их найти: эмпирическое исследование взаимосвязи между нестабильными тестами и тестовыми антипаттернами посредством изучения зависимости от порядка выполнения тестов». Бакалаврская диссертация, кафедра компьютерных и информационных наук, Университет Линчёпинга, 2022. LIU-IDA/LITH-EX-G–19/056–SE. PDF
- Лайнен, Фабиан, Даниэль Эльснер, Александр Пречнер, Андреас Штальбауэр, Михаэль Зайлер и Эльмар Юргенс. «Стоимость нестабильных тестов в непрерывной интеграции: промышленное исследование». Мюнхенский технический университет и CQSE GmbH, Мюнхен, Германия, 2023. PDF
Ресурсы
- Как устранить недетерминированность в тестах, Мартин Фаулер, 2011
- Больше никаких нестабильных тестов в команде Go, Паван Сударшан, 2012
- Сборка, которая кричала «Сбой»: как заслужить доверие к тестам непрерывной интеграции — доклад (видео) Энджи Джонс на SeleniumConf Austin 2017
- Подкаст Test and Code: нестабильные тесты и способы борьбы с ними, Брайан Оккен и Энтони Шоу, 2018
-
Microsoft:
- Как мы тестируем VSTS для обеспечения непрерывной поставки, Брайан Харри, Microsoft, 2017
- Устранение нестабильных тестов — публикация в блоге и доклад (видео) Мунила Шаха, 2017
-
Google:
- Нестабильные тесты в Google и способы борьбы с ними, Джон Микко, 2016
- Откуда берутся нестабильные тесты Google?, Джефф Листфилд, 2017
- Dropbox: * Athena: наша автоматизированная система управления состоянием сборки, Утсав Шах, 2019 * Как управлять нестабильными тестами в рабочих процессах CI, Ли Хаойи, 2025
- Uber: * Работа с нестабильными модульными тестами в Java, Uber Engineering, 2021 * Масштабное обновление подхода к нестабильным тестам в Uber, Uber Engineering, 2024
© 2015–2026 Holger Krekel and pytest-dev team
Licensed under the MIT License.
https://docs.pytest.org/en/stable/explanation/flaky.html