How to parametrize Hypothesis strategy in @given

Question:

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?

Asked By: Bewang

||

Answers:

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.

Answered By: Zac Hatfield-Dodds
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.