Search code examples
pythonpytestpython-hypothesis

Combining unit and property-based tests in pytest and Hypothesis


I need to run a mixture of unit tests and property-based tests in Python. My current test code runs them separately, and thus duplicates some code:

@pytest.mark.parametrize("values", list_of_values)
def test_my_function(a_value):
    call_test(a_value)

@given(st.arbitrary_values())
def test_hypothesis_my_function(a_value):
    call_test(a_value)

There's a code repetition above: test_my_function and test_hypothesis_my_function are the same, just triggered by unit and property-based infrastructure respectively.

I would prefer to eliminate the code repetition above to obtain something like this:

@pytest.mark.parametrize("values", list_of_values)
@given(st.arbitrary_values())
def test_my_function(a_value):
    call_test(a_value)

Can this effect be attained? Thanks in advance.


Solution

  • If your parameter list is a literal in the source code you can translate that to a sequence of @example() decorators:

    @given(text())
    @example("Hello world")
    @example(x="Some very long string")
    def test_some_code(x):
        pass
    

    If it's an explicit list you can write a helper function to apply them for you:

    def parametrize(list_of_args):
        def inner(f):
            for a in list_of_kwargs:
                f = hypothesis.example(*a)(f)
            return f
        return inner
    
    @parametrize(list_of_args_tuples)
    @given(text())
    def test_some_code(x):
        pass