How do you clean up resources at the end of a pytest session?

Viewed 733

I have a suite of selenium end to end tests. I instantiate one webdriver.ChromeDriver instance that I pass as a fixture to every test in the suite.

'''python3
@pytest.fixture(scope="session")
def driver(request):
    return d(request)
'''

After the last test runs I want to close the webdriver instance with driver.quit().

I can accomplish this with a fixture

@pytest.hookimpl(trylast=True)
def close_after_test_suite(driver, requests):
    if requests:
        driver.quit()

However this only runs if tests do not fail during the suite. If every test passes, the browser will close. If a single test fails then the browser will be left open.

How can I use pytest to close my browser at the end of the test suite regardless of whether or not tests fail?

1 Answers

If you want to run some code on teardown, use yield instead of return, for example:

@pytest.fixture(scope="session")
def driver(request):
    driver = d(request)
    yield driver
    driver.quit()

However, the selenium.webdriver.WebDriver classes implement the context manager magic methods, so you can also use the with statement:

@pytest.fixture(scope="session")
def driver(request):
    with d(request) as driver:
        yield driver

Another (although pretty old, but still working) option is using the request.addfinalizer option:

@pytest.fixture(scope="session")
def driver(request):
    driver = d(request)

    def f():
        driver.quit()

    request.addfinalizer(f)
    return driver
Related