9

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?

Georgy
  • 12,464
  • 7
  • 65
  • 73
Bewang
  • 453
  • 3
  • 18

1 Answers1

9

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.

Zac Hatfield-Dodds
  • 2,455
  • 6
  • 19
  • Please update the answer with the correct syntax as many have probably suggested (edit queue is full) `@pytest.mark.paramterize('req_type', ['dated', 'dateless'])` – ConstantinB Nov 25 '22 at 13:03