1

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.

Jim
  • 229
  • 1
  • 4
  • Have you tried the latter? What happened? – enzo Dec 08 '21 at 04:47
  • Good question, thank you. pytest complains that `test_my_function: function uses no argument 'values'`. This also happens if I swaap the @pytest and @given calls. – Jim Dec 08 '21 at 04:55
  • 1
    Please add imports and some sample code for `call_test` so the code is runnable. I tried importing `import hypothesis.strategies as st`, but just got AttributeError for missing `arbitrary_values` – Tzane Dec 08 '21 at 08:08

1 Answers1

1

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
Zac Hatfield-Dodds
  • 2,455
  • 6
  • 19