Yield Fixtures

Introduction

When writing Selenium tests with PyTest, it’s important to ensure that resources such as browser sessions are cleaned up properly after every test. If a browser is not closed correctly, it can consume system resources and affect subsequent test executions.

A Yield Fixture provides an elegant way to perform both setup and teardown within a single fixture. Code written before the yield statement executes before the test begins, while code written after yield runs automatically after the test finishes—even if the test fails.

In this tutorial, you’ll learn how Yield Fixtures work in PyTest, how they simplify Selenium automation, and why they are the preferred approach for managing browser setup and cleanup.


What are Yield Fixtures?

A Yield Fixture is a PyTest fixture that uses the yield statement to divide the fixture into two parts:

  • Setup (before yield)

  • Teardown (after yield)

Example:

          Test Starts

               │

               ▼

        Setup Code

    (Launch Browser)

               │

               ▼

           yield

               │

               ▼

        Execute Test

               │

               ▼

      Teardown Code

(Delete Cookies & Close Browser)

The browser is prepared before the test starts and automatically cleaned up after the test finishes.


Why Use Yield Fixtures?

Yield Fixtures help you:

  • Automate browser setup and cleanup.

  • Avoid duplicate teardown code.

  • Improve test reliability.

  • Ensure resources are always released.

  • Build cleaner automation frameworks.


How Yield Fixtures Work

A Yield Fixture uses the yield statement to separate setup and teardown.

Example:

@pytest.fixture
def browser():
    driver = webdriver.Chrome()

    yield driver

    driver.quit()

Everything before yield performs the setup.

Everything after yield performs the cleanup.


Example

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


# Topic: 40. Fixtures - Yield Fixtures
# Practice site: https://www.testmuai.com/selenium-playground/input-form-demo
# Run: pytest -s 40_examples/test_03_yield_fixtures.py
#
# Code before yield is setup. Code after yield is teardown and always runs when
# the test finishes, even if it fails.


@pytest.fixture
def cleaned_browser():
    driver = webdriver.Chrome()
    driver.maximize_window()
    yield driver
    driver.delete_all_cookies()
    driver.quit()


def test_yield_fixtures(cleaned_browser):
    cleaned_browser.get("https://www.testmuai.com/selenium-playground/input-form-demo")

    name = cleaned_browser.find_element(By.ID, "name")
    name.send_keys("Selenium User")

    assert name.get_attribute("value") == "Selenium User"

Understanding the Code

Import Required Libraries

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

These modules are required to:

  • Create PyTest fixtures.

  • Launch the Chrome browser.

  • Locate web elements.


Create a Yield Fixture

@pytest.fixture
def cleaned_browser():

The @pytest.fixture decorator tells PyTest that cleaned_browser() is a reusable fixture.

Whenever a test requests the cleaned_browser fixture, PyTest executes it automatically.


Launch the Browser

driver = webdriver.Chrome()

Creates a new Chrome browser session.

This is part of the fixture’s setup phase.


Maximize the Browser Window

driver.maximize_window()

Maximizes the browser window before executing the test.

This helps ensure consistent element visibility across different screen resolutions.


Pause the Fixture Using yield

yield driver

The yield statement passes the browser instance to the test function.

PyTest pauses the fixture here while the test executes.

Once the test completes, PyTest resumes execution with the code following yield.


Delete All Browser Cookies

driver.delete_all_cookies()

Removes all cookies stored during the test execution.

This helps prevent leftover session data from affecting future tests.


Close the Browser

driver.quit()

Closes all browser windows and ends the WebDriver session.

This teardown step executes automatically after every test, even if the test encounters an error.


Open the Practice Website

cleaned_browser.get(
    "https://www.testmuai.com/selenium-playground/input-form-demo"
)

Navigates to the Input Form Demo page.


Locate the Name Field

name = cleaned_browser.find_element(
    By.ID,
    "name"
)

Locates the Name input field using its ID.


Enter the Name

name.send_keys("Selenium User")

Enters the text Selenium User into the input field.


Verify the Entered Value

assert name.get_attribute(
    "value"
) == "Selenium User"

The assert statement verifies that the value entered into the textbox matches the expected text.

If the values do not match, PyTest marks the test as failed.


Practical Example

Suppose your Selenium automation suite executes hundreds of form validation tests.

Each test should:

  • Launch a browser.

  • Execute the test.

  • Clear cookies.

  • Close the browser.

A Yield Fixture performs these tasks automatically, eliminating repetitive cleanup code.


Automation Testing Example

Consider an online shopping application.

Each test needs to:

  • Open the browser.

  • Log in to the application.

  • Execute the shopping workflow.

  • Remove session cookies.

  • Close the browser.

Using a Yield Fixture ensures that every test starts with a clean browser session.


Real-World Example

Yield Fixtures are commonly used in:

  • Selenium automation frameworks

  • Regression testing

  • Cross-browser testing

  • API automation

  • Data-driven testing

  • CI/CD pipelines

  • Enterprise automation projects

Most professional Selenium frameworks use Yield Fixtures to manage browser setup and teardown efficiently.


Advantages of Yield Fixtures

  • Combine setup and teardown in one fixture.

  • Automatically clean up resources.

  • Reduce duplicate code.

  • Improve test reliability.

  • Simplify framework maintenance.


Common Mistakes Beginners Make

Using return Instead of yield

Using return ends the fixture immediately.

Use yield whenever cleanup code needs to execute after the test.


Forgetting Cleanup Code

Always place browser cleanup after the yield statement to prevent unused browser sessions from remaining open.


Writing Teardown Before yield

Only setup code should appear before yield.

Cleanup operations belong after yield.


Assuming Teardown Runs Only on Successful Tests

Code after yield executes whether the test passes or fails.

This ensures proper resource cleanup in all situations.


Best Practices

  • Use yield instead of return for Selenium fixtures.

  • Keep setup code before yield.

  • Place cleanup code after yield.

  • Always close the browser using driver.quit().

  • Clear cookies when browser isolation is required.

  • Keep fixtures simple and reusable.


Conclusion

Yield Fixtures are the recommended way to manage setup and teardown in PyTest. By separating browser initialization from cleanup using the yield statement, they produce cleaner, more maintainable, and more reliable Selenium automation tests. They also ensure that browser sessions are properly cleaned up, even when tests fail unexpectedly.


Frequently Asked Questions (FAQs)

What is a Yield Fixture?

A Yield Fixture is a PyTest fixture that uses the yield statement to separate setup and teardown code.


Why use yield instead of return?

The yield statement allows PyTest to execute cleanup code after the test completes.

With return, the fixture ends immediately and teardown code does not execute.


When does the code after yield execute?

The code after yield executes automatically after the test finishes, regardless of whether the test passes or fails.


Can I perform browser cleanup after yield?

Yes.

Operations such as driver.delete_all_cookies() and driver.quit() are commonly placed after the yield statement.


Why are Yield Fixtures recommended for Selenium?

Yield Fixtures simplify browser management, reduce duplicate code, ensure reliable cleanup, and improve the overall maintainability of Selenium automation frameworks.


Key Takeaways

  • Yield Fixtures separate setup and teardown using the yield statement.

  • Code before yield performs setup.

  • Code after yield performs cleanup.

  • Cleanup code executes even if the test fails.

  • Yield Fixtures are the recommended approach for Selenium browser management in PyTest.

  • Proper use of Yield Fixtures helps build reliable and maintainable automation frameworks.