Reputation: 363
I'm new on python and pytest, and at the momment I understand the basic of how work. But I can't find documentation to the below scenario:
I created a generic fixture that have the default mock values used in my project, and use this fixture in tests, it works fine. Something like:
#fixture
@pytest.fixture()
def generic_fixture(mocker):
mocker.patch('project.some_class.url', "http://some_url:5002")
#test
def test_1(generic_fixture):
do_something() # method that uses values from my generic fixture
assert True
Now I want to know if have a way to pass a parameter in my test to my fixture call, to make some decision, something like:
#fixture
@pytest.fixture()
def generic_fixture(mocker, parameter_url):
if parameter_url == None
mocker.patch('project.some_class.url', "http://some_url:5002")
else:
mocker.patch('project.some_class.url', parameter_url)
#test
def test_1(generic_fixture(parameter_url)):
do_something() # method that uses values from my generic fixture
assert True
How I can do It properly? I looked at monkeypath, @pytest.mark.parametrize and some other structures, but none of them look to do what I want.
Upvotes: 3
Views: 1281
Reputation: 363
The answer of D Malan help me a lot!
I'll put here my final solution, because I used what the above answer describe and other things, and I think it can be usefull for someone with similar structure, because at least for my was hard to figure it out (If is preferable, someone note me so I put this answer in the question):
conftest.py
def pytest_configure(config):
# to avoid warnings
config.addinivalue_line("markers", "my_fixture_url")
@pytest.fixture()
def my_fixture(request):
if request.node.get_closest_marker("my_fixture_url") and request.node.get_closest_marker("my_fixture_url").args[0]:
something = request.node.get_closest_marker("my_fixture_url").args[0]
else:
something = 'www.google.com'
...
test.py
@pytest.mark.my_fixture_url({'url': 'www.stackoverflow.com'})
def test_1(my_fixture):
...
def test_2(my_fixture):
...
I used a dictionary in my mark because I have situations where I want send more than one parameter, and/or use each one to override some default value.
Note I have a second test using the fixture but without marker. I can do it and use the default values from fixture.
This way I can use the same fixture in cases where I want the default values and in cases where I need to override part of the fixture configuration.
I hope it help someone :D
Upvotes: 1
Reputation: 11484
You can use Pytest's marks for this.
#fixture
@pytest.fixture()
def generic_fixture(request, mocker):
parameter_url = request.node.get_closest_marker("generic_fixture_url")
...
#test
@pytest.mark.generic_fixture_url("url")
def test_1(generic_fixture):
...
Other options are to turn your fixture into a factory or to set some attribute on the module of your test.
Upvotes: 3