Reputation: 89
Does anyone know of a workaround to dynamically parametrize a pytest test.
Example:
resp = []
def test_1():
r = requests.get(<some url>)
resp = <parse a list out of response r>
@pytest.mark.parameterize("response",resp)
def test_2(response):
<Use resp values and pass it one by one to another api>
I came across the following issue on pytest github which is almost same as my issue.
https://github.com/pytest-dev/pytest/issues/3273
As per this discussion, pytest parametrizes test before execution of any test. Runtime parametrization is not supported. Does anyone know of a workaround or a pythonic way to handle this behavior?
Upvotes: 1
Views: 1487
Reputation: 512
Adrian Krupa's answer is close, now add response parametrization:
CANNED_RESPONSES = dict(OK=200, REDIRECT=304, SERVER_ERROR=500)
RESPONSE = 'response'
def pytest_generate_tests(metafunc):
if RESPONSE in metafunc.fixturenames:
ids = list(CANNED_RESPONSES.keys())
responses = list(CANNED_RESPONSES.values())
metafunc.parametrize(RESPONSE, responses, ids=ids)
def test_flar(response):
print response
This way you can get named ids in -v and multiple tests for a set of canned answers:
test_in.py::test_flar[OK] 200
PASSED
test_in.py::test_flar[REDIRECT] 304
PASSED
test_in.py::test_flar[SERVER_ERROR] 500
PASSED
Upvotes: 1
Reputation: 1937
Don't make the tests to depend on each other. It's not a good practice as described here.
If you want to reuse request response you can wrap it into a fixture.
@pytest.fixture(scope="module")
def response():
import requests
return requests.get(<some url>)
def test(response):
<Use resp values and pass it one by one to another api>
It would be also a good idea to mock the request to make tests independent from a remote resource. You can use responses library for that.
import responses
import requests
@responses.activate
def test_simple():
responses.add(responses.GET, 'http://twitter.com/api/1/foobar',
json={'error': 'not found'}, status=404)
resp = requests.get('http://twitter.com/api/1/foobar')
Upvotes: 1