Imagine the following test-suite:
import pytest
@pytest.fixture(scope="session")
def global_resource():
yield
if ...:
print("output generated by this resource.")
def test_foo():
assert False
def test_bar(global_resource):
assert True
def test_baz(global_resource):
assert True
In my actual setup, global_resource
starts a docker container that produces a ton of output. If a test that uses that fixture fails, I want to print that output. If none of the tests that use this fixture fail, I do not want to print it.
In other words:
foo | bar | baz | print? |
---|---|---|---|
True | True | True | no |
True | True | False | yes |
True | False | True | yes |
True | False | False | yes |
False | True | True | no |
False | True | False | yes |
False | False | True | yes |
False | False | False | yes |
Is there something that I can put into the condition after global_resource
's yield in order to learn if I want to print or no? I am aware that at this point tests may still fail due to issues in their teardown, that is ok.
global_resource
is in session
scope, so you will have only the bottom line of the tests in request
fixture, something like testsfailed=3, testscollected=6
You can use pytest_runtest_makereport
hook in conftest.py
to check every test
FAILED_GLOBAL_RESOURCE_TEST = False
@pytest.fixture(scope='session')
def global_resource():
yield
if FAILED_GLOBAL_RESOURCE_TEST :
print('output generated by this resource.')
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
global FAILED_GLOBAL_RESOURCE_TEST
outcome = yield
result = outcome.get_result()
if result.failed and result.when == 'call' and 'global_resource' in item.fixturenames:
FAILED_GLOBAL_RESOURCE_TEST = True
This will print the docker output only once, but if you wanted to print on every test failure you need only minor changes (keep the output from global_resource
and use it in pytest_runtest_makereport
).