Хабрахабр

[Перевод] Hypothesis — параметры

Эта статья является переводом страницы Hypothesis -Settings взятой из официального руководства.

*Прим. переводчика:*

Александра Шорина на "Moscow Python Meetup 50". Лично я не смог найти какой то полезной информации на русском языке по использованию Гипотезы, кроме выступления 23 ноября 2017 г. Возможно этот перевод окажется полезен не только мне.

Hypothesis пытается использовать приемлемые значения в умолчаниях для своего поведения, но иногда этого недостаточно, и вам требуется настроить его.

Вы можете изменить базовые настройки теста на основе @given с помощью декоратора настроек: Механизм для этого — объект hypothesis.settings.

Вызов @given выглядит следующим образом:

from hypothesis import given, settings @given(integers())
@settings(max_examples=500)
def test_this_thoroughly(x): pass

При этом используется объект hypothesis.settings, в результате чего тест получает гораздо больший набор примеров, чем обычный.

Это не повлияет на результаты. Он может быть применен либо до, либо после given. И поэтому в точности эквивалентен предыдущему следующий пример:

from hypothesis import given, settings @settings(max_examples=500)
@given(integers())
def test_this_thoroughly(x): pass

Доступные установки

`class hypothesis.settings(parent=None, kwargs)`**

Они могут контролировать как стратегию фальсификации, так и детали генерируемых данных. Объект settings управляет множеством параметров, используемых при фальсификации.

Значения по умолчанию выбираются из объекта settings.default и изменения будут подхвачены во вновь созданные настройки.

classmethod define_setting(name, description, default, options=None, validator=None, show_default=True, future_default=not_set, deprecation_message=None, hide_repr=not_set) [source]

Добавление нового setting.

  • name-имя свойства, которое будет использоваться для доступа к настройке. Это должен быть действительный идентификатор python.
  • description-описание появится в docstring свойства
  • default-используется значение по умолчанию. Это может быть функция с нулевым аргументом, в этом случае она вычисляется, и ее результат сохраняется при первом обращении к ней для любого заданного объекта settings.

buffer_size

Если вам нужно создать действительно большие примеры, вы можете увеличить это значение, но это сделает ваши тесты медленнее. Размер исходных данных, используемых для генерации примеров.

Значение по умолчанию: 8192

database

ExampleDatabase, который будет использоваться для сохранения примеров и загрузки предыдущих примеров. Экземпляр hypothesis.database. Может быть None, в этом случае хранилище не будет использоваться, :memory: для базы данных в памяти или любой путь для базы данных примеров на основе каталогов.

Значение по умолчанию: (dynamically calculated)

database_file

Расположение файла или каталога для сохранения и загрузки ранее опробованных примеров; :memory: для кэша в памяти или None, чтобы полностью отключить кэширование.

Значение по умолчанию: (dynamically calculated)

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

deadline

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

Установите значение None, чтобы полностью отключить это поведение.

На данный момент выдается HypothesisDeprecationWarning, если вы превысите этот крайний срок по умолчанию и не указали явный срок. В будущем это значение будет по умолчанию до 200.

Значение по умолчанию: not_set

derandomize

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

Значение по умолчанию: False

max_examples

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

Значение по умолчанию: 100

max_iterations

По факту ничего не делает, но остается по соображениям совместимости.

Значение по умолчанию: not_set

Это уже не имеет никакого эффекта. Параметр max_iterations отключен, поскольку для этой цели более эффективны внутренние эвристики, чем пользовательская настройка.

max_shrinks

При превышении этого порога Hypothesis предположит, что что-то пошло немного не так, и прекратит попытки уменьшить пример. Контролирует число выполненных успешных сокращений примера.

Значение по умолчанию: 500

min_satisfying_examples

По факту ничего не делает, но остается по соображениям совместимости.

Значение по умолчанию: not_set

Параметр min_satisfying_examples устарел и отключен из-за перекрытия с параметром filter_too_much healthcheck и плохого взаимодействия с параметром max_examples.

perform_health_check

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

Значение по умолчанию: not_set

Этот параметр устарел, так как perform_health_check=False дублирует эффект suppress_health_check=HealthCheck.all() Используйте его вместо этого!

phases

Дополнительную информацию смотрите в полной документации Контролирует, какие фазы должны быть запущены.

Значение по умолчанию: (<Phase.explicit: 0>, <Phase.reuse: 1>, <Phase.generate: 2>, <Phase.shrink: 3>)

print_blob

Определяет, следует ли печатать BLOB (большие двоичные объекты) после тестов, которые можно использовать для воспроизведения ошибок.

Более подробную информацию об этом поведении смотрите в документации по @reproduce_failure.

INFER: 1> Значение по умолчанию: <PrintSettings.

stateful_step_count

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

Значение по умолчанию: 50

strict

По иронии судьбы, включение этой функции является ошибкой — она ​​существует только для того, чтобы пользователи получали правильный тип ошибок! strict (строгий) режим был объявлен устаревшим в пользу стандартных предупреждений Python.

Значение по умолчанию: False

Чтобы получить такое же поведение, используйте warnings.simplefilter(‘error’, HypothesisDeprecationWarning). Строгий режим устарел и исчезнет в будущей версии Hypothesis.

suppress_health_check

Список отключаемых проверок работоспособности.

Значение по умолчанию: ()

timeout

Это мягкий, а не жесткий предел — Hypothesis не будет прерывать выполнение вызываемой функции, чтобы остановить ее. Как только будет достигнуто это значение в секундах, фальсификация завершится, даже если она не нашла какие то примеры. Если это значение <= 0, то таймаут не будет применен.

Значение по умолчанию: 60

Для получения ожидаемого в будущем поведения установите timeout=hypothesis.unlimited вместо этого (который будет оставаться действительным в течение дальнейшего периода устаревания после того, как этот параметр исчезнет). Параметр timeout устарел и будет удален в будущей версии Hypothesis.

use_coverage

Следует ли использовать информацию о покрытии для улучшения способности Hypothesis находить ошибки.

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

Значение по умолчанию: True

verbosity

Контроль уровня детализации Hypothesis сообщений.

Значение по умолчанию: Verbosity.normal

Controlling What Runs

Hypothesis делит тесты на четыре логически различные фазы:

  1. Выполнение явных примеров provided with the @example decorator.
  2. Повторный запуск выборки ранее неудачных примеров для воспроизведения ранее замеченной ошибки.
  3. Создание новых примеров.
  4. Попытка сжать пример, найденный на этапах 2 или 3, до более управляемого (явные примеры не могут быть сжаты).

Phase : Настройка фаз обеспечивает точный контроль над тем, какая из них выполняется, при этом каждая фаза соответствует значению в перечислении hypothesis._settings.

  1. Phase.explicit управляет выполнением явных примеров.
  2. Phase.reuse управляет повторным использованием предыдущих примеров.
  3. Phase.generate определяет, будут ли создаваться новые примеры.
  4. Phase.shrink управляет сокращением (сжатием) примеров.

например, settings(phases=[Phase.generate, Phase.shrink]) будет генерировать новые примеры и сжимать их, но не будет запускать явные примеры или повторно использовать предыдущие сбои, в то время как settings(phases=[Phase.explicit]) будут выполняться только явные примеры. Аргумент phases принимает коллекцию с любым их подмножеством.

Просмотр промежуточного результата

Она работает, как с ~hypothesis.core.find, так и с @given. Чтобы увидеть, что происходит, пока Hypothesis выполняет ваши тесты, вы можете включить в настройке Verbosity.

>>> from hypothesis import find, settings, Verbosity
>>> from hypothesis.strategies import lists, integers
>>> find(lists(integers()), any, settings=settings(verbosity=Verbosity.verbose))
Tried non-satisfying example []
Found satisfying example [-1198601713, -67, 116, -29578]
Shrunk example to [-67, 116, -29578]
Shrunk example to [116, -29578]
Shrunk example to [-29578]
Shrunk example to [-115]
Shrunk example to [115]
Shrunk example to [-57]
Shrunk example to [29]
Shrunk example to [-14]
Shrunk example to [-7]
Shrunk example to [4]
Shrunk example to [2]
Shrunk example to [1]
[1]

normal-это значение по умолчанию, в то время как в quiet режиме Hypothesis не будет ничего печатать, даже окончательный пример фальсификации. Четыре уровня: quiet (тихий), normal (нормальный), verbose (подробный) и debug (отладочный). Вы, наверное, не хотите этого. debug по сути это то тот же verbose, но немного подробнее.

При использовании pytest также может потребоваться disable output capturing for passing tests (запись выходных данных для прохождения тестов).

Сборка settings objects

Любые отсутствующие будут установлены по умолчанию: Settings могут быть созданы путем вызова hypothesis.settings с любым из доступных значений settings.

>>> from hypothesis import settings
>>> settings().max_examples
100
>>> settings(max_examples=10).max_examples
10

В качестве первого аргумента можно также передать объект — "родительский" settings, и любые параметры, не указанные в качестве именованных аргументов, будут скопированы из родительских параметров:

>>> parent = settings(max_examples=10)
>>> child = settings(parent, deadline=200)
>>> parent.max_examples == child.max_examples == 10
True
>>> parent.deadline
not_set
>>> child.deadline
200

Умолчания в settings

Помимо того, что объект settings сам по себе, так и все вновь созданные объекты settings, которые явно не основаны на других настройках, основаны на значениях по умолчанию, поэтому будут наследовать любые значения, которые явно не установлены. В любой момент в вашей программе есть текущие настройки по умолчанию, доступные в качестве settings.default.

следующий раздел), но их также можно переопределить локально с помощью объекта параметров в качестве context manager Значения по умолчанию можно изменить с помощью профилей (См.

>>> with settings(max_examples=150):
... print(settings.default.max_examples)
... print(settings().max_examples)
150
150
>>> settings().max_examples
100

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

Это можно использовать, вложив определения тестов в контекст:

from hypothesis import given, settings with settings(max_examples=500): @given(integers()) def test_this_thoroughly(x): pass

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

Это происходит потому, что менеджер контекста влияет только на определение, а не на выполнение функции. Внимание!: Если вы используете определение тестовых функции, которые не используют @given внутри блока контекста, они не будут использовать вложенные параметры.

settings Profiles

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

Эти профили могут быть загружены в любое время. Hypothesis позволяет определить различные настройки профилей.

Загрузка профиля изменяет параметры по умолчанию, но не изменяет поведение тестов, которые явно изменяют параметры.

>>> from hypothesis import settings
>>> settings.register_profile("ci", max_examples=1000)
>>> settings().max_examples
100
>>> settings.load_profile("ci")
>>> settings().max_examples
1000

Вместо загрузки профиля и переопределения значений по умолчанию можно получить профили для определенных тестов.

>>> with settings.get_profile("ci"):
... print(settings().max_examples)
...
1000

Это Рекомендуемый шаблон для выполнения тестов в CI. При необходимости можно определить переменную окружения для загрузки профиля. Если эта переменная не определена, будут загружены значения по умолчанию, определенные Hypothesis. Приведенный ниже код должен выполняться в conftest.py или любой раздел setup/initialization комплекта тестов.

>>> import os
>>> from hypothesis import settings, Verbosity
>>> settings.register_profile("ci", max_examples=1000)
>>> settings.register_profile("dev", max_examples=10)
>>> settings.register_profile("debug", max_examples=10, verbosity=Verbosity.verbose)
>>> settings.load_profile(os.getenv(u'HYPOTHESIS_PROFILE', 'default'))

Если вы используете плагин hypothesis pytest и ваши профили зарегистрированы вашим conftest вы можете загрузить один с опцией командной строки --hypothesis-profile.

$ pytest tests --hypothesis-profile

Timeouts

На данный момент парметры timeout все еще могут быть назначены, и старое умолчание timeout в одну минуту остается. Функционал timeout Hypothesis является устаревшим и будет удален.

Если вы хотите в будущем использовать свой код, вы можете оценить его поведение в будущем, установив timeout в hypothesis.unlimited.

from hypothesis import given, settings, unlimited
from hypothesis import strategies as st @settings(timeout=unlimited)
@given(st.integers())
def test_something_slow(i): ...

timeout=unlimited останется допустимым параметром после отказа от функции timeout (но затем будет иметь свой собственный цикл старения). Это приведет к тому, что ваш код будет выполняться до тех пор, пока он не подберет обычный пример в рамках Hypothesis, независимо от того, сколько времени это займет.

Если вы действительно хотите, чтобы ваш тест выполнялся вечно, следующий код позволит это: Тем не менее, теперь существует проверка работоспособности, связанная со сроками и health check, который предназначен, чтобы отловить тесты, которые готовы работать веками.

from hypothesis import given, settings, unlimited, HealthCheck
from hypothesis import strategies as st @settings(timeout=unlimited, suppress_health_check=[ HealthCheck.hung_test
])
@given(st.integers())
def test_something_slow(i): ...

Обратно

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть