И вынести тестируемые результаты вне кода. Это статья об автоматизации и увеличения удобства тестирования на Python.  У меня был проект, который разрабатывался уже несколько лет. В проекте отсутствовали тесты. А также у него были активные зависимости от других команд, которые также влияли на результат. Регрессионное тестирование было одним из шагов для более уверенной разработки. Его суть в сравнении вычисленных данных с последним канонизированным результатом работы программы.  Результаты выполнения можно проверять в python коде тестов. Это близко к контексту выполнения и зачастую удобно. Но это также может быть неудобно когда: Я пытался подобрать решение к этим задачам, а получилась своя небольшая библиотека. Вот как эти задачи решаются с помощью библиотеки testoot для Питона 3.4+. Подход используется в модульных и юнит тестах. Файлы результатов складываются в отдельной директории репозитория. Интересующая нас функция foo генерирует результат вычисления. Добавляем возвращаемое значение в тест: Запустим тесты с pytest: В первый запуск автоматически создастся файл результата и сохранится в директории тестов. В последующие запуски вычисленное будет сверяться с записанным значением. Что такое фикстура testoot типа Testoot опишу ниже. Если после первого запуска изменим возвращаемое значение на другое: То получим AssertionError при запуске тестов: Посмотрим как можно сохранить новое значение в тестах. По-умолчанию тесты запускаются в автоматическом режиме и не спрашивают пользователя об изменении сохранённых данных. Перезапустим тесты с флагом --canonize. Теперь покажется сравнение в том же виде, в котором даёт pytest (флаги --verbose также работают): На вопрос канонизировать ли тест можем ответить утвердительно и тогда будет сохранены новые данные. В противном случае выводится ошибка как и без флага запуска. Результаты хранятся в файлах репозитория рядом с кодом. Текущие форматы сериалиации:  Идеального формата для задач, где и поддерживаются все типы и в VCS легко повторно проконтролировать изменения пока нет. Ещё из возможностей. Генерируем файл и отправляем содержимое под наблюдение. Выше использовали фикстуры типа Testoot. Рассмотрим ближе что это такое: DefaultBaseTestoot это базовый объект с логикой тестирования. Для создания Testoot к нему добавляется контекст теста (scope='function'). Из pytest фикстуры request узнаём название теста, с которым сохраняем получившийся результат. Сам DefaultBaseTestoot это BaseTestoot с заданными настройками по-умолчанию: сохраняем данные в директорию .testoot с pickle-сериализатором, включаем канонизацию при флаге --canonize. Если хотим изменить сериализатор по-умолчанию: Точно также можно менять хранилище и компаратор для объектов. Компаратор для pytest выглядит стандартно и переопределяется для нужных тестов: Сериализатор и компаратор переопределяются на уровне контекста PytestContext(request, serializer=BinarySerializer(), comparator=PytestComparator()). Или уже на уровне самого теста: Переопределения в тесте имеют приоритет над контекстом, которые сами приоритетнее значений в BaseTestoot. Может быть проблема слишком большого объёма данных, что канонизировать придётся на каждый чих в коде. Да, такая же проблема с гранулярностью обыкновенных тестов.  Также может потребоваться удаление постоянно изменяющихся элементов из данных таких как дата последнего изменения. Чтобы такие изменения не проникали внутрь сохранённых данных. Это был обзор тестирования и возможностей библиотеки для Python. Буду рад комментариям и предложениям! Установка: pip3 install testoot
Документация: https://testoot.readthedocs.io
Исходный код: https://github.com/aptakhin/testoot Программист