pythonpython-hypothesis

How to parametrize Hypothesis strategy in @given


I'm testing a REST API, which can process different requests, e.g., dated and dateless. A request has a field called request_type. I'm wondering what's the best way to write test in hypothesis:

I can write two testes, one for dated, and the other is for dateless.

But for a common property, can I write one test which combine with pytest.mark.parametrize. The problem is how the request strategy uses that parameter req_type in @given.

@pytest.mark.parameterize('req_type', ['dated', 'dateless'])
@given(req=requests())
def test_process_request(req, req_type):
   # override the parameter req_type in req with input req_type
   pass

Is there a way to parametrize like @given(req=requests(req_type))? Or shall I just generate requests with dated and dateless randomly and pass into the test?


Solution

  • You can't do it all in external decorators, since they're (lazily) evaluated at import time, but you can use the data() strategy to draw a value inside your test function.

    @pytest.mark.parametrize('req_type', ['dated', 'dateless'])
    @given(data=st.data())
    def test_process_request(req_type, data):
        req = data.draw(requests(req_type))
        ...
    

    Alternatively, if you can get the req_type from the req object, it is probably more elegant to generate either type and pass them into the test:

    @given(req=st.one_of(requests(dateless), requests(dated)))
    def test_process_request(req):
        req_type = req.type
        ...
    

    I'd prefer the latter as it's a bit less magical, but the former does work if you need it.