PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchUse @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.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errors#1 Best Overall
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.
Rank #2
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.
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.
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.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.
Best Value
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.
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.
Quick Recap
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.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →




