Change a way fixtures are called in pytest
Here is an example of running my conftest.py function that prints "A" before my test function that prints "B".
cd to the parent directory, for this example it is py_tests and run.
pytest -s -v
The output is:
A
setting up
B
PASSED
With directory structure:
py_tests
-conftest.py
-tests
--tests.py
Files:
conftest.py
import pytest
@pytest.fixture(scope="function")
def print_one():
print("\n")
print("A")
test.py
import pytest
class Testonething:
@pytest.fixture(scope="function", autouse=True)
def setup(self, print_one):
print("setting up")
def test_one_thing(self):
print("B")
assert True
Since your _wrapper
is a function-scoped autouse fixture: it will be instantiated before other fixtures within the same scope. So, hot fix is to define _wrapper
without autouse=True
and try to call that decorator implicitly like:
def test_abc(_wrapper):
assert 1==0
Autouse source
[Update] If you don't have an ability to change your test suites, I suggest you just wipe all local specific _wrapper
and refactor your conftest-specified fixture to call _wrapper
, because fixture functions can use other fixtures themselves. Your conftest.py
will be look like this:
# conftest.py
@pytest.fixture(scope="function", autouse=True)
def _wrapper(pause_on_assert):
print("pre condition")
yield
print("post condition")
@pytest.fixture()
def pause_on_assert():
yield
if hasattr(sys, 'last_value') and isinstance(sys.last_value, AssertionError):
tkinter.messagebox.showinfo(sys.last_value)
Modularity source
If you want to ensure a piece of code runs after the test function, but before all fixtures teardown, I'd advise to use the pytest_runtest_teardown
hook instead. Replace the pause_on_assert
fixture in your conftest.py
with:
def pytest_runtest_teardown(item, nextitem):
if hasattr(sys, 'last_value') and isinstance(sys.last_value, AssertionError):
tkinter.messagebox.showinfo(sys.last_value)