Open torcolvin opened 4 years ago
Bisected to bb878a2b13508e88ace7718759065de56a63aac5 (runner: don't try to teardown previous items from pytest_runtest_setup) from #7368 - cc @bluetech
Thanks for the great report @torcolvin, and @The-Compiler for the bisection.
What happens here is:
pytest_runtest_teardown
hook impl is registered last, and so runs first.pytest itself uses the pytest_runtest_teardown
hook for some work, and assumes that it runs. Thus the scenario breaks it.
I consider it more of an issue with the user code than a regression in pytest, but maybe others will disagree.
In any case the simplest fix for you would be
@pytest.hookimpl(trylast=True)
def pytest_runtest_teardown(item, nextitem):
....
This makes your hookimpl run after pytest does its thing. This would have been a good idea even in previous pytest versions.
i think using pytest.hookimpl(trylast=True)
could be a good idea in the use case I have this case, but if more than one plugin registers a teardown hook, we can end up right back where we started. I can see why this situation might be unavoidable, but maybe the exception assert colitem in self.stack
could say something about this happening because a previous teardown raised an exception? Or maybe an exception raised here should terminate the test harness, since further results are invalidated?
I can see why this situation might be unavoidable, but maybe the exception assert colitem in self.stack could say something about this happening because a previous teardown raised an exception?
I think we can improve that exception message as you suggest.
FWIW, I used an autouse fixture for the same purpose in the past:
@pytest.fixture(autouse=True)
def ensure_cleanup():
yield
cleanup_all_resources()
Fixtures raising an exception are expected and pytest handles them correctly, but with hooks things are a bit more delicate.
Raising an exception in
pytest_runtest_teardown
in one test will cause an exception in all subsequent tests. This is a regression from 5.2.4 and earlier releases. I use exceptions inpytest_runtest_teardown
to assert resource cleanup for all tests regardless of other fixtures that are used. It's unusual to fail in this manner, but this makes it look like all tests are failing.Here is the output from pytest 6.0.1, where it marks test_a as a failure in the expected fashion. However it marks test_b as a failure with
assert colitem in self.stack
. If there are more tests, all tests will be marked with the same failure message as test_b.Here's is the output from pytest 5.4.3
To reproduce, I use two files:
conftest.py
test_exception.py
pip list from python 3.8.2 on ubuntu 20.04