Эссе о разработке игр, мышлении и книгах

Python Hypothesis

Давно хотел посмотреть на hypothesis — генератор фикстур для тестов. Сделал это пока в очередной раз колупал типы в Python.

Hypothesis позволяет описывать генераторы входных данных для тестов и запускать тесты сразу на всех сочетаниях данных. В случае ошибки библиотека попробует локализовать её в наиболее простом наборе данных, чтобы было проще понять проблему и воспроизвести ей. Генераторы для базовых типов идут в комплекте, поэтому деление на ноль она ловит хорошо :-)

Если кратко, то мне понравилось, рекомендую, буду использовать, но не всегда. Подробнее под катом.

Плюсы

В долгосрочной перспективе улучшает структуру кода и структуру тестов в частности.

Очень поможет в верификации сложной логики, когда все варианты: сочетания параметров, последовательности исполнения — не помещаются в голове. Когда я экспериментировал с coulson, hypothesis нашла много ошибок в сравнении типов, которое мне пришлось делать самостоятельно.

Хорошо подходит для увеличения надёжности устоявшегося проекта: поможет структурировать тесты и, возможно, уменьшить количество кода в них.

Найденные ошибки хранит в собственной базе и проверяет их в первую очередь при запуске тестов.

Чтобы эффективно писать тесты, нужны дисциплина и специфические навыки. Чтобы писать тесты с гипотезой необходимо ещё больше дисциплины и навыков. В долгосрочной перспективе — это однозначный плюс, но порог входа увеличивается.

Минусы

Недостатков тоже хватает, но они не перевешивают профит.

Логика работы не всегда прозрачна, местами не хватает документации. Поэтому порог входа выше, чем мог бы быть.

В популяризаторских статьях библиотека часто преподносится как «волшебная палочка», которая с помощью внутренней магии сама находит все ошибки. На самом деле магии в ней меньше, чем кажется. В частности, hypothesis не определит самостоятельно все крайние случаи в вашей предметной области — их надо прописывать в генераторы самостоятельно.

Тесты начинают работать кратно медленнее, так как каждый запускается по разу на все возможные сочетания входных данных. Библиотека не подберёт автоматически идеальный минимальный набор случаев, поэтому будет проверять «лишнее».

Слабо интегрирована с pytest — pytest создаёт (свои) фикстуры для всего теста, а не для каждого отдельного запуска. Это надо учитывать.

Слабо подходит для прототипирования, особенно для его начала. Если у вас активно меняются интерфейсы и модели данных, то вместе с основным кодом придётся рефакторить и генераторы гипотезы.

Итого

Если вы ещё помните как учились писать тесты и адаптированный код для них, то у вас возникнут схожие ощущения при начале работы с hypothesis. Как по необходимости выворачивать мозги, так и по выгоде такого выворачивания.

Добавлено 25.03.2022

Какое-то время пробовал использовать Hypothesis для пет-проектов (Тарантоги).

Пришёл к выводу, что библиотека плохо приспособлена для тестирования бизнес-логики, но хорошо подходит для тестирования числодробилок и конвертеров данных.

Тестировать бизнес-логику гипотезой можно, но это долго. Как по времени написания тестов, так и по времени их работы. Особенно, если вы прототипируете.

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

Если вам надо тестировать сложную логику, рекомендую использовать параметризацию тестов в pytest. Она позволит проще и гарантированнее покрывать все необходимые сочетания условий для тех же конечных автоматов.

А вот если вам нужно протестировать какой-нибудь бинарный протокол передачи данных, то тут уже можно смотреть на Hypothesis в чистом виде или на её сочетание с той же параметризацией в pytest.