October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk6 min

How to Parameterize Selenium Tests with pytest

Use pytest parameterization for Selenium test data or browser choices, with fixture teardown, readable IDs, focused reruns, and practical troubleshooting.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use @pytest.mark.parametrize when a test needs several sets of input data, and use a parametrized fixture when the cases should configure the WebDriver itself. For either approach, give cases readable IDs and close each browser with driver.quit() in fixture teardown. This guide shows how to choose the right pattern, run individual cases, and diagnose common failures.

Parameterize ordinary Selenium test inputs

When the browser setup is the same but the test needs to check several URLs, titles, or other values, pass those values directly to the test with @pytest.mark.parametrize. Keep WebDriver creation and cleanup in a fixture:

import pytest
from selenium import webdriver

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

@pytest.mark.parametrize(
    "url, expected_title",
    [
        pytest.param("https://example.com/", "Example Domain", id="example"),
        pytest.param("https://www.selenium.dev/", "Selenium", id="selenium-home"),
    ],
)
def test_page_title(driver, url, expected_title):
    driver.get(url)
    assert expected_title in driver.title

pytest runs the test once per parameter set, supplying each URL and expected title to the function. The URLs and expected titles here illustrate the pattern; they are not claims that these pages were tested. See the pytest parametrization guide for the framework’s parameterization options.

Keep browser lifetime separate from test data

The driver fixture owns the browser resource; the decorator supplies data. The fixture yields the WebDriver so pytest has a teardown point after each use, then calls quit() to end the session. This is the fixture arrangement shown in Selenium’s Python API documentation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Make cases identifiable

Use pytest.param(..., id="...") for individual cases or ids=... on the decorator. Names such as example and selenium-home make collected cases and failure output easier to interpret. A parameter case can also carry a mark, such as pytest.param(value, id="known-issue", marks=pytest.mark.xfail), when that status is intentional.

Parameterize the browser fixture

When each case should create a different browser, put the choices on the fixture. pytest exposes the current choice through request.param:

import pytest
from selenium import webdriver

@pytest.fixture(params=["chrome", "firefox"], ids=["chrome", "firefox"])
def driver(request):
    if request.param == "chrome":
        browser = webdriver.Chrome()
    elif request.param == "firefox":
        browser = webdriver.Firefox()
    else:
        raise AssertionError(f"Unsupported browser: {request.param}")

    yield browser
    browser.quit()

def test_homepage_has_title(driver):
    driver.get("https://example.com/")
    assert "Example Domain" in driver.title

Every test that requests this fixture runs for each fixture parameter, so this example creates a Chrome and Firefox session for the test. Adapt construction to the browsers and runtime your project supports. This is a pattern assembled from pytest’s fixture-parameter behavior and Selenium’s fixture examples; it is not presented as an executed test.

Use indirect parameters when setup should happen at test time

Choose indirect=True when a test parameter is configuration for a fixture rather than a direct test-function value. pytest passes the value to the fixture as request.param; this keeps potentially expensive resource setup out of collection:

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import pytest
from selenium import webdriver

@pytest.fixture
def driver(request):
    browser_name = request.param
    if browser_name == "chrome":
        browser = webdriver.Chrome()
    elif browser_name == "firefox":
        browser = webdriver.Firefox()
    else:
        raise ValueError(f"Unsupported browser: {browser_name}")

    yield browser
    browser.quit()

@pytest.mark.parametrize("driver", ["chrome", "firefox"], indirect=True,
                         ids=["chrome", "firefox"])
def test_homepage_title(driver):
    driver.get("https://example.com/")
    assert "Example Domain" in driver.title

For a test with several parameters, set indirect=["driver"] to route only the browser argument through a fixture, leaving other arguments as direct test data.

Choose the right parameterization level

Pattern Use it for Where values arrive
@pytest.mark.parametrize URLs, expected text, or explicit case records As test-function arguments
@pytest.fixture(params=...) A resource choice, such as browser type, shared by tests that request the fixture Through request.param inside the fixture
indirect=True Test-declared values that should configure fixture setup Through request.param inside the selected fixture
pytest_generate_tests Cases generated dynamically, for example from a command-line option or collection-time rule As generated test parameters

For a short, fixed list, a decorator or fixture parameter list is simpler than a generation hook. Use pytest_generate_tests when the cases genuinely depend on dynamic collection logic.

Control combinations, state, and runtime

Know how many cases pytest will run

Stacking parameter decorators creates combinations across the parameter sets. For example, three URLs and two browsers produce six test cases when every combination applies. Use that only when the behavior needs the full matrix; otherwise define the combinations you actually intend to cover.

Avoid mutating shared parameter objects

pytest passes parameter values as-is and does not copy them for each invocation. If a test mutates a list or dictionary supplied as a parameter, later cases can observe that changed object. Avoid mutation or create a fresh object in a fixture when isolation matters.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Balance coverage with isolation

  • Choose the smallest set of input/browser combinations that exercises the behavior you need.
  • Decide whether each case needs a fresh WebDriver session; reusing sessions can allow cookies, local storage, or other browser state to leak between tests.
  • Account for browser launches when using fixture parameters across many tests. A broader matrix increases setup and execution work.
  • Keep cases as an explicit list when that is easiest to maintain; use fixtures for resource configuration and dynamic generation only when the case source requires it.

Run or rerun one parameter case

pytest includes parameter IDs in test node IDs. Given the first example’s test path and ID, run just that case with:

pytest tests/test_pages.py::test_page_title[selenium-home]

Replace the file path, function name, and bracketed ID with the actual collected node ID in your project. If unsure of the exact ID, collect the tests and inspect pytest’s reported names before selecting a case.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Set up Selenium and diagnose common failures

Browser or driver cannot start

Check that the selected browser is installed and available in the environment where pytest runs. Current Selenium documentation says Selenium Manager handles browser and driver installation for most supported platforms and browsers; explicit installation or driver specification remains an option if that does not fit your environment. Confirm behavior against the Selenium version installed in your project, since supported versions and setup details can change.

One case fails after another case passes

Check whether a test or fixture mutated a shared parameter value, or whether browser state is being reused. Parameter objects are not copied automatically, and browser sessions can retain state. Avoid modifying shared objects and ensure your fixture’s lifetime matches the isolation you require.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The test runs more times than expected

Inspect stacked parameter decorators and parametrized fixtures: each combination can multiply the number of invocations. Narrow the inputs or browser choices to the combinations relevant to the test.

Teardown does not run after setup fails

Place browser creation and teardown in a yielding fixture, and structure setup so teardown is registered as soon as the resource exists. A try/finally around browser use can make cleanup explicit in more complex setup. Selenium’s Python documentation demonstrates the yielded-fixture pattern with driver.quit().

Local versus remote browser execution

Selenium’s documentation says local scripts do not need the Java server. Remote WebDriver execution requires Selenium Grid. If using a remote environment, adapt fixture construction for that Grid rather than treating it like a locally launched browser.

Or skip the browser setup

For a screenshot of a page rather than an interactive Selenium test, ScreenshotNeo provides a one-request screenshot API. It does not replace pytest assertions or Selenium interactions, but can avoid setting up a browser locally for capture-only tasks. See the ScreenshotNeo API documentation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com/ -o shot.webp

Cookie and consent banners are accepted and removed before capture, along with supported newsletter popups and chat widgets. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers identify the page verdict and billing status. ScreenshotNeo also offers an MCP server with screenshot, page-info, and PDF tools for AI agents. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Sign up for the free plan.

Frequently Asked Questions

Can pytest parameterize only some arguments indirectly?

Yes. Pass the selected fixture argument names in a list, such as indirect=["driver"]; other parameters remain direct test-function inputs.

Does pytest copy lists or dictionaries used as parameters?

No. Parameter values are passed as-is, so avoid mutating shared objects or construct fresh values for each invocation.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. Shenzhen desk3 min
    HONOR Expands Beyond Smartphones With Humanoid Robot RevealHONOR said it unveiled its first humanoid robot at MWC 2026 and named shopping assistance, workplace inspections, and supportive companionship as intended uses. Later Robotics D1 claims and a reported…
  2. Cupertino desk5 min
    Apple Unveils AirPods Max 2: The Upgrade That Should Have Happened Years AgoAirPods Max 2 adds H2-powered audio features and Apple claims up to 1.5× more effective ANC, but its design, Smart Case, and 20-hour battery rating are unchanged. Wired lossless audio…
  3. Cupertino desk4 min
    Apple’s OLED Touch MacBooks Are Coming—but the Dynamic Island Is the Real GambleApple has not announced an OLED touchscreen MacBook, but reports point to high-end models arriving in late 2026 or early 2027. The reported Mac Dynamic Island could be useful, but…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.