📜 ⬆️ ⬇️

Hypothesis parameters

Settings


This article is a translation of the Hypothesis -Settings page taken from the official manual.


* Approx. translator: *

Personally, I could not find any useful information in Russian on the use of the Hypothesis, except for the speech on November 23, 2017 of Alexander Shorin on " Moscow Python Meetup 50 ". Perhaps this translation will be useful not only for me.


Hypothesis tries to use acceptable values ​​in defaults for its behavior, but sometimes this is not enough, and you need to configure it.


The mechanism for this is the object of hypothesis.settings . You can change the basic test settings based on @given using the settings decorator:


The @given call looks like this:


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

In this case, the hypothesis.settings object is used, with the result that the test receives a much larger set of examples than the usual one.


It can be applied either before or after given . This will not affect the results. Therefore, the following example is exactly equivalent to the previous one:


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

Available installations

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


The settings object controls a number of parameters used in tampering. They can control both the falsification strategy and the details of the generated data.


The default values ​​are selected from the settings.default object and the changes will be picked up in the newly created settings.


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]

Adding a new setting.


  • name is the name of the property that will be used to access the setting. This must be a valid python id.
  • description description will appear in docstring properties
  • default -the default value is used. This may be a function with a zero argument, in which case it is calculated, and its result is saved when it is first accessed for any given settings object.

buffer_size

The size of the source data used to generate the examples. If you need to create really big examples, you can increase this value, but it will make your tests slower.


Default value: 8192


database

An instance of hypothesis.database.ExampleDatabase that will be used to save the examples and load the previous examples. Maybe None, in this case the storage will not be used ,: memory: for the database in memory or any way for the database of examples based on directories.


Default value: (dynamically calculated)


database_file

The location of the file or directory to save and load previously tested examples; : memory: for cache in memory or None to completely disable caching.


Default value: (dynamically calculated)


The database_file parameter is deprecated in favor of the database parameter and will be removed in the next version. It exists only for complex historical reasons, and it is highly recommended that you use the database instead.


deadline

If set, this time is in milliseconds (the value can be a floating point number for expressing smaller units of time), which can not exceed every single example (i.e., every time the test function is called, but not the entire validated test) in the test. Tests that take longer than this value can be converted to errors (but this will not always happen if the value is close to the deadline to allow some flexibility during the test).


Set the value to None to completely disable this behavior.


In the future, this value will default to 200. At this point, HypothesisDeprecationWarning is issued, if you exceed this deadline by default and have not specified an explicit date.


Default value: not_set


derandomize

If True, the hypothesis will work in a deterministic mode, where each falsification uses a random number generator based on the falsification hypothesis, which will be matched on several runs. This has the advantage that any randomness from your tests will be eliminated, which may be preferable for some situations. This has the disadvantage of making your tests less likely to search for new emergencies.


Default value: False


max_examples

As soon as this set of satisfying examples is considered without finding any counter-example, the falsification will cease.


Default value: 100


max_iterations

In fact, does nothing, but remains for compatibility reasons.


Default value: not_set


The max_iterations option is disabled because internal heuristics are more efficient for this purpose than user settings. It already has no effect.


max_shrinks

Controls the number of successful examples abbreviations performed. If you exceed this threshold, Hypothesis will assume that something went a bit wrong and will stop trying to reduce the example.


Default value: 500


min_satisfying_examples

In fact, does nothing, but remains for compatibility reasons.


Default value: not_set


The min_satisfying_examples parameter is obsolete and disabled due to overlapping with the filter_too_much healthcheck parameter and poor interaction with the max_examples parameter.


perform_health_check

If set to True, Hypothesis will perform a preliminary health check before attempting to actually run the test.


Default value: not_set


This parameter is deprecated because perform_health_check = False duplicates the effect suppress_health_check = HealthCheck.all () Use it instead!


phases

Controls which phases should be started. For more information, see the full documentation.


The default value is: (<Phase.explicit: 0>, <Phase.reuse: 1>, <Phase.generate: 2>, <Phase.shrink: 3>)


print_blob

Specifies whether to print BLOBs (blobs) after tests that can be used to reproduce errors.


For more information about this behavior, see the @reproduce_failure documentation.


Default value: <PrintSettings.INFER: 1>


stateful_step_count

The number of steps to run a program with state tracking before abandoning its decomposition.


Default value: 50


strict

The strict (strict) mode has been deprecated in favor of standard Python warnings. Ironically, the inclusion of this feature is a mistake - it only exists so that users get the right type of error!


Default value: False


Strict mode is outdated and will disappear in a future version of Hypothesis. To get the same behavior, use warnings.simplefilter ('error', HypothesisDeprecationWarning) .


suppress_health_check

List of disabled health checks.


Default value: ()


timeout

Once this value is reached in seconds, the fraud will end, even if it has not found some examples. This is a soft, not hard limit - Hypothesis will not interrupt the execution of the called function to stop it. If this value is <= 0, then the timeout will not be applied.


Default value: 60


The timeout parameter is obsolete and will be removed in a future version of Hypothesis. For future expected behavior, set timeout = hypothesis.unlimited instead (which will remain valid for a further period of obsolescence after this parameter disappears).


use_coverage

Whether to use coating information to improve Hypothesis's ability to find bugs.


Usually you should leave this value True, unless of course the code starts to work badly when executed under the cover. If you still had to turn off this value, please send an error message or add a comment to an existing problem that caused you to do this.


Default value: true


verbosity

Control the level of detail hypothesis messages.


Default value: Verbosity.normal


Controlling What Runs


Hypothesis divides the tests into four logically different phases:


  1. Running explicit examples provided with the @example decorator .
  2. Re-run a sample of previously unsuccessful examples to reproduce a previously noticed error.
  3. Creating new examples.
  4. Attempt to compress the example found in steps 2 or 3 to a more manageable one (explicit examples cannot be compressed).

Phase tuning provides precise control over which of them is performed, with each phase corresponding to the value in the hypothesis._settings.Phase listing:


  1. Phase.explicit manages the execution of explicit examples.
  2. Phase.reuse manages the reuse of previous examples.
  3. Phase.generate determines whether new examples will be created.
  4. Phase.shrink manages the reduction (compression) of examples.

The phases argument takes a collection with any subset of them. for example, settings(phases=[Phase.generate, Phase.shrink]) will generate new examples and compress them, but will not run explicit examples or reuse previous failures, while settings(phases=[Phase.explicit]) only explicit examples will be executed.


View intermediate result


To see what happens while Hypothesis performs your tests, you can enable Verbosity in the configuration. It works with both ~hypothesis.core.find and @given .


 >>> 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] 

Four levels: quiet (quiet), normal (normal), verbose (detailed) and debug (debug). normal is the default value, while in quiet mode hypothesis will not print anything, even the final example of tampering. debug is essentially the same verbose, but in a bit more detail. You probably do not want this.


When using pytest, you may also need to disable output capturing for passing tests (writing output for passing tests).


Build settings objects


Settings can be created by calling hypothesis.settings with any of the available settings. Any missing will be set by default:


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

As the first argument, you can also pass an object - the "parent" settings, and any parameters not specified as named arguments will be copied from the parent parameters:


 >>> 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 

Default settings


At any time in your program there are current default settings available as settings.default . In addition to the settings object itself, all newly created settings objects that are not explicitly based on other settings are based on default values, so they will inherit any values ​​that are not explicitly set.


Default values ​​can be changed using profiles (See the next section), but they can also be overridden locally using the parameters object as the context manager


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

Note that after exiting the block, the default value returns to normal.


This can be used by putting test definitions in context:


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

All created settings objects or tests defined inside the block inherit default values ​​from the settings object used as context. Of course, you can still redefine them with custom settings.


Caution !: If you use the definition of test functions that do not use @given inside the context block, they will not use nested parameters. This is because the context manager only affects the definition, not the execution of the function.


settings profiles


Depending on the environment, various default parameters may be required. For example: during development, you can reduce the number of examples to speed up the tests. However, in the CI environment, more examples may be required in order to more likely find errors.


Hypothesis allows you to define various profile settings. These profiles can be downloaded at any time.


Loading a profile changes the default settings, but does not change the behavior of tests that explicitly change the parameters.


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

Instead of loading a profile and overriding default values, you can get profiles for specific tests.


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

If necessary, you can define an environment variable for loading the profile. This is the recommended template for running tests in CI. The code below should run in conftest.py or any setup / initialization section of the test suite. If this variable is not defined, the default values ​​determined by Hypothesis will be loaded.


 >>> 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')) 

If you are using the hypothesis pytest plugin and your profiles are registered with your conftest, you can load one with the command line --hypothesis-profile .


 $ pytest tests --hypothesis-profile 

Timeouts


The timeout hypothesis functionality is obsolete and will be removed. At this time, the timeout parameters can still be assigned, and the old default timeout remains in one minute.


If you want to use your code in the future, you can evaluate its behavior in the future by setting the timeout to 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): ... 

This will cause your code to be executed until it selects the usual example within the Hypothesis framework, no matter how long it takes. timeout=unlimited will remain a valid parameter after dropping the timeout function (but then will have its own aging cycle).


However, there is now a health check associated with deadlines and health check, which is designed to catch tests that are ready to work for centuries. If you really want your test to run forever, the following code will allow this:


 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): ... 

Back


')

Source: https://habr.com/ru/post/354318/


All Articles