Введение
Обычные тесты проверяют, что функция работает при заданных значениях. Но что, если вы не знаете заранее, какие входные данные приведут к ошибке? Hypothesis – генеративное тестирование решает эту проблему.
Hypothesis — это библиотека property-based testing для Python. Она автоматически генерирует входные данные, стремясь найти крайние, ошибочные или нестандартные случаи. Вместо ручного подбора аргументов, вы описываете свойства функции, и Hypothesis пытается их нарушить.
Установка и базовый пример
Установка:
Базовый тест:
Запуск через pytest
или python -m unittest
.
Основы генерации данных
-
Декоратор
@given()
указывает, какие стратегии генерации использовать -
Стратегии находятся в
hypothesis.strategies
(чаще всего импортируется какst
)
Примеры стратегий:
Проверка свойств и инвариантов
Hypothesis лучше всего работает, когда вы проверяете общие свойства (invariants), а не конкретные значения.
Например, строка в верхнем регистре должна быть в isupper()
:
Это позволяет находить баги, которые невозможно покрыть вручную.
Минимизация ошибок (shrinkage)
Если тест упал, Hypothesis:
-
Сохраняет минимальный набор входных данных, вызвавший ошибку
-
Выводит его для повторного использования
Пример:
Вывод: Falsifying example: test_fails_on_zero(x=0)
Стратегии генерации данных
Некоторые стратегии из hypothesis.strategies
:
-
integers()
-
text()
-
lists(elements=...)
-
dictionaries(keys=..., values=...)
-
booleans()
-
dates()
,datetimes()
-
emails()
,urls()
-
binary()
,just(value)
Можно создавать сложные комбинации:
Или пользовательские:
Фильтрация и допущения
Если нужно отфильтровать нежелательные значения:
Или использовать assume()
:
Параметризация и множественные сценарии
Для конкретных примеров используйте @example()
:
Интеграция с Pytest и UnitTest
С Pytest:
С UnitTest:
Тестирование API и бизнес-логики
Hypothesis может генерировать:
-
JSON-данные
-
Строки запроса
-
Случайные параметры API
Пример генерации словаря:
Генерация пользовательских типов и моделей
Можно создавать кастомные стратегии:
Поддерживается генерация моделей Pydantic и объектов SQLAlchemy.
Контроль повторяемости и дебаг
Использование @settings()
:
Фиксация случайности:
Сравнение с другими инструментами
Инструмент | Генерация данных | Авто-поиск граничных | Поддержка property-based | Интеграция с Pytest |
---|---|---|---|---|
Hypothesis | Да | Да | Да | Отличная |
Pytest | Частично | Нет | Нет | Да |
Fuzzing (Atheris, AFL) | Да | Частично | Нет | Сложнее |
Рекомендации и лучшие практики
-
Проверяйте свойства, а не конкретные результаты
-
Используйте
assume()
и фильтры с осторожностью -
Избегайте
assert x != x
— Hypothesis может не найти ошибки в edge-cases -
Добавляйте
@example()
для покрытия краевых значений
Часто задаваемые вопросы (FAQ)
1. Что такое Hypothesis?
Это библиотека генеративного тестирования (property-based testing) для Python.
2. Как работает Hypothesis?
Она генерирует входные данные и ищет такие, при которых функция не выполняет заданные условия.
3. Поддерживает ли Hypothesis интеграцию с Pytest?
Да, полностью.
4. Можно ли тестировать API с Hypothesis?
Да, особенно полезно для проверки валидаторов и сериализаторов.
5. Как повторить найденную ошибку?
Hypothesis выводит failing example и сохраняет их в .hypothesis
для повторного запуска.
6. Где лучше не использовать Hypothesis?
Когда поведение функции зависит от внешних состояний (время, сеть, глобальные переменные).
Полный справочник по ключевым функциям и модулям библиотеки Hypothesis для Python
Установка
Базовое использование
Декоратор | Описание |
---|---|
@given(...) |
Главный декоратор — указывает, какие данные генерировать. |
Стратегии (hypothesis.strategies
)
Hypothesis использует стратегии для генерации значений разных типов.
Стратегия | Описание |
---|---|
integers() |
Целые числа |
floats() |
Числа с плавающей точкой |
booleans() |
True / False |
text() |
Unicode-строки |
emails() |
Валидные e-mail |
dates() , datetimes() |
Даты и времена |
lists(sub_strategy) |
Списки |
dictionaries(keys, values) |
Словари |
tuples(a, b) |
Кортежи |
just(x) |
Всегда возвращает x |
sampled_from([a, b, c]) |
Случайный элемент из списка |
one_of(...) |
Один из нескольких стратегий |
Ограничение диапазонов и фильтрация
Фильтрация | Примеры |
---|---|
integers(min_value=1, max_value=10) |
Числа от 1 до 10 |
.filter(lambda x: ...) |
Убирает значения, не проходящие фильтр |
.map(func) |
Трансформация значения |
Комбинирование стратегий
Проверка ошибок и assume()
Метод | Описание |
---|---|
assume(cond) |
Прерывает пример, если условие не выполнено (не ошибка). |
Управление количеством и сложностью тестов
Аргумент | Описание |
---|---|
@settings(...) |
Настройки выполнения: число примеров, таймаут и т.д. |
max_examples , deadline , verbosity |
Параметры @settings |
Использование с pytest
Hypothesis прекрасно работает с pytest
"из коробки". Просто запускайте pytest
— все @given
-тесты будут выполняться.
Использование с unittest
Проверка строк
Проверка структур и объектов
Отладка и воспроизведение ошибок
Механизм | Описание |
---|---|
При падении Hypothesis выводит минимальный пример, вызывающий ошибку. | |
Чтобы воспроизвести ошибку, можно установить переменную: | |
HYPOTHESIS_PROFILE=debug и использовать --hypothesis-seed . |
Полезные утилиты
Функция | Описание |
---|---|