0
votes

I'm setting up some configuration in conftest.py for rerunning failed pytest tests in specific cases.

This function has been added to conftest.py. The idea is that a test can be set to retry by using the request fixture to set request.node.retry to True.

def pytest_runtest_protocol(item, nextitem):
"""Checks for manual mark and if found, reruns test if requested"""
if item.get_closest_marker("manual") is None:
    return

# Infinite loop for rerunning tests
while True:
    # Run test and get result
    item.ihook.pytest_runtest_logstart(
        nodeid=item.nodeid,
        location=item.location
    )

    # Hangs on this line on retry
    reports = runtestprotocol(item, nextitem=nextitem)

    # Check results
    if not getattr(item, 'retry', False):
        for report in reports:
            item.ihook.pytest_runtest_logreport(report=report)
        return True
    else:
        delattr(item, 'retry')

This works when multiple tests are being run, but if only one test is being run, or the test is the last in a series, then the first failure of the test causes teardown of all fixtures. Function-level fixtures are fine to be set up again (in fact, I want them to be to ensure clean state) but session-level fixtures are also torn down, and I need them to restart the test.

Is there any way to prevent the session-level fixture teardown until I'm ready?

1

1 Answers

0
votes

The solution to this was a bit of a hack - it's adding a dummy test that doesn't get logged.

Install pytest-ordering. Add a new file with a dummy test somewhere marked as last, e.g.

@pytest.mark.last
def test_dummy():
    assert True

Then in the pytest_runtest_protocol function, skip the dummy test right at the start:

def pytest_runtest_protocol(item, nextitem):
    if item.name == 'test_dummy':
        return False
    # Rest of function

As the last function will always be the dummy function which can't be retried, the session fixtures will be valid going into the test and will only be torn down afterwards.