I am looking for a way run some pytest unit tests from Python and register a pytest fixture dynamically. As explained in in the Pytest documentation, when running tests programmatically their behaviour can be altered with a custom plugin. I have the following setup
validation.py (contains the tests to run)
def test_valid(new_fixture):
assert new_fixture > 0
which is launched with,
import pytest
new_fixture_value = 36
class FixtureRegPlugin(object):
def pytest_sessionstart(self):
print('Test session start')
@pytest.fixture
def new_fixture():
return new_fixture_value
pytest.main(['-sv', './validation.py'], plugins=[FixtureRegPlugin()])
here we run tests in validation.py with a custom plugin that registers a hook for pytest_sessionstart. This hook is executed at the beginning of the test session, and I can see the printed output as expected. However, the new_fixture is not registered, and so the test fails with a "fixture not found" error.
The goal is to modify the result of the fixture at runtime and so I cannot just place its definition inside validation.py.
Is there any reason you don't want to use @pytest.fixture(scope='session') in a conftest.py file rather than writing your own plugin? Could that achieve the functionality of altering the fixture at runtime that you're looking for?
In any case, if you change your indentation and add self to new_fixture's arguments it should work.
@pytest.fixture
def new_fixture():
return new_fixture_value
to
@pytest.fixture(scope='session')
def new_fixture(self):
return new_fixture_value
You can view setup and teardown with --setup-show on the command line.
Contents of "script.py":
import pytest
class FixtureRegPlugin(object):
@pytest.fixture(scope='session')
def session_fixture(self):
pass
@pytest.fixture(scope='module')
def module_fixture(self):
pass
@pytest.fixture(scope='function')
def function_fixture(self):
pass
pytest.main(['--setup-show', './validation.py'], plugins=[FixtureRegPlugin()])
Contents of validation.py:
def test_A(session_fixture, module_fixture, function_fixture):
pass
def test_B(session_fixture, module_fixture, function_fixture):
pass
Running python script.py:
Test session start
=================================== test session starts
platform linux -- Python 3.6.2, pytest-3.2.2, py-1.4.34, pluggy-0.4.0
rootdir: /home/stackoverflow, inifile:
collected 2 items
validation.py
SETUP S session_fixture
SETUP M module_fixture
SETUP F function_fixture
validation.py::test_A (fixtures used: function_fixture, module_fixture, session_fixture).
TEARDOWN F function_fixture
SETUP F function_fixture
validation.py::test_B (fixtures used: function_fixture, module_fixture, session_fixture).
TEARDOWN F function_fixture
TEARDOWN M module_fixture
TEARDOWN S session_fixture
=================================== 2 passed in 0.00 seconds
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