I have a python test that uses a fixture for credentials (a tuple of userid and password)
def test_something(credentials)
(userid, password) = credentials
print("Hello {0}, welcome to my test".format(userid))
and I have pytest fixture for credentials:
@pytest.fixture()
def credentials():
return ("my_userid", "my_password")
It works great
Now I want to extend this for multiple credentials (say staging and production) so that my test will run twice (once each for staging and production).
I thought that parameterization was the answer, but it seems I can't parameterize with fixtures.
I would love to do something like this:
@pytest.fixture(params=[staging_credentials, production_credentials])
def credentials(request):
return request.param
where staging_credentials and production_credentials are all fixtures:
@pytest.fixture()
def staging_credentials():
return ("staging_userid", "staging_password")
@pytest.fixture()
def production_credentials():
return ("prod_userid", "prod_password")
but apparently parameters to the fixture can't be other fixtures.
Any suggestions on how to elegantly handle this? I've looked at https://docs.pytest.org/en/latest/proposals/parametrize_with_fixtures.html but that seems a but too brute force.
Thanks! Steve
Indirect parametrization is the answer. So, the parameters to the fixtures CAN be other fixtures (by their name/code).
import pytest
all_credentials = {
'staging': ('user1', 'pass1'),
'prod': ('user2', 'pass2'),
}
@pytest.fixture
def credentials(request):
return all_credentials[request.param]
@pytest.mark.parametrize('credentials', ['staging', 'prod'], indirect=True)
def test_me(credentials):
pass
Technically, you can not only get a dict value by its key, but generate the credentials
result based on request.param
, and this param will be the value passed to the same-name parameter of the test.
If you want other fixtures to be used (probably because of the setup/teardown stages, as this is the only reason to do so):
import pytest
@pytest.fixture
def credentials(request):
return request.getfuncargvalue(request.param)
@pytest.fixture()
def staging_credentials():
return ("staging_userid", "staging_password")
@pytest.fixture()
def production_credentials():
return ("prod_userid", "prod_password")
@pytest.mark.parametrize('credentials', ['staging_credentials', 'production_credentials'], indirect=True)
def test_me(credentials):
pass
Here, request.getfuncargvalue(...)
will return a fixture value by the fixture name, dynamically.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With