---
title: Set up Selenium with Python and pytest | TestingBot
description: 'This chapter gets a browser opening from a pytest test. It takes about
  ten minutes, most of which is installing things once. ## Check your Python version…'
source_url:
  html: https://testingbot.com/resources/courses/selenium-python/setup-and-first-test
  md: https://testingbot.com/resources/courses/selenium-python/setup-and-first-test.md
---

Course

[Selenium with Python and pytest](https://testingbot.com/resources/courses/selenium-python)

Chapter 2 of 10

1. [1 Selenium Python Tutorial with pytest](https://testingbot.com/resources/courses/selenium-python)
2. [2 Set up Selenium with Python and pytest](https://testingbot.com/resources/courses/selenium-python/setup-and-first-test)
3. [3 Selenium locators in Python: the By API](https://testingbot.com/resources/courses/selenium-python/locators)
4. [4 Selenium waits in Python: WebDriverWait and time.sleep](https://testingbot.com/resources/courses/selenium-python/waits)
5. [5 pytest fixtures for Selenium: conftest.py and scope](https://testingbot.com/resources/courses/selenium-python/pytest-fixtures)
6. [6 Assertions, screenshots on failure and test reports](https://testingbot.com/resources/courses/selenium-python/assertions-screenshots-reports)
7. [7 Page objects in Python](https://testingbot.com/resources/courses/selenium-python/page-objects)
8. [8 Run Selenium tests in parallel with pytest-xdist](https://testingbot.com/resources/courses/selenium-python/parallel-with-pytest-xdist)
9. [9 Run Selenium Python tests on the TestingBot grid](https://testingbot.com/resources/courses/selenium-python/run-on-testingbot)
10. [10 Selenium Python Quiz](https://testingbot.com/resources/courses/selenium-python/knowledge-check)

[Exit course](https://testingbot.com/resources/courses)

 Chapter 2 of 10 Intermediate 5 min read 1 quick check Updated Nov 2026 

# Set up Selenium with Python and pytest
On this page
1. [Check your Python version](https://testingbot.com#check-your-python-version)
2. [Create a project and a virtual environment](https://testingbot.com#create-a-project-and-a-virtual-environment)
3. [Install Selenium and pytest](https://testingbot.com#install-selenium-and-pytest)
4. [No driver downloads: Selenium Manager](https://testingbot.com#no-driver-downloads-selenium-manager)
5. [Your first test](https://testingbot.com#your-first-test)
6. [What just happened](https://testingbot.com#what-just-happened)
7. [Headless runs](https://testingbot.com#headless-runs)
8. [Useful pytest flags from day one](https://testingbot.com#useful-pytest-flags-from-day-one)

This chapter gets a browser opening from a pytest test. It takes about ten minutes, most of which is installing things once.

## Check your Python version[#](https://testingbot.com#check-your-python-version)

```bash
python3 --version
```

You need 3.10 or newer. On Windows the command is usually `py --version`. If your system Python is older, install a current one from [python.org](https://www.python.org/downloads/) or your package manager rather than upgrading the system copy.

## Create a project and a virtual environment[#](https://testingbot.com#create-a-project-and-a-virtual-environment)

A virtual environment keeps this project's packages separate from every other Python project on your machine. Always use one for test suites: it is what makes "works on my machine" reproducible in CI.

```bash
mkdir selenium-python-course
cd selenium-python-course
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
```

Your prompt now starts with `(.venv)`. Every `pip` and `pytest` command from here on runs inside it. Add `.venv/` to `.gitignore`; the environment is rebuilt from `requirements.txt`, never committed.

## Install Selenium and pytest[#](https://testingbot.com#install-selenium-and-pytest)

Create `requirements.txt` with pinned versions:

```
selenium==4.52.0
pytest==9.2.0
pytest-xdist==3.8.0
pytest-html==4.2.0
testingbotclient==0.2.0
```

and install it:

```bash
pip install -r requirements.txt
```

Only the first two are needed right away. pytest-xdist (chapter 7), pytest-html (chapter 5) and the TestingBot API client (chapter 8) are listed now so the file does not change under you later. Pinning exact versions means a new release cannot break your suite on a Monday morning; upgrade deliberately, run the suite, then commit the new pins.

## No driver downloads: Selenium Manager[#](https://testingbot.com#no-driver-downloads-selenium-manager)

A browser is controlled through a driver binary: chromedriver for Chrome, geckodriver for Firefox, msedgedriver for Edge. Older tutorials have you download it, unzip it and put it on your `PATH`, then repeat that every time Chrome auto-updates.

Since Selenium 4.6 you skip all of that. When you call `webdriver.Chrome()`, Selenium runs **Selenium Manager** , a small binary bundled inside the `selenium` package. It detects which browser version is installed, downloads the matching driver if it is not cached yet, and stores it under `~/.cache/selenium`. You can watch it work by setting `SE_DEBUG`:

```bash
SE_DEBUG=1 python -c "from selenium import webdriver; d = webdriver.Chrome(); d.quit()"
```

Among the output you will see lines like these (versions will differ on your machine):

```
chromedriver not found in PATH
Detected browser: chrome 157.0.8103.78
Required driver: chromedriver 157.0.8103.78
```

One trap: if an old chromedriver _is_ on your `PATH`, Selenium uses it, and you get `SessionNotCreatedException: This version of ChromeDriver only supports Chrome version N`. The fix is to delete the stray driver, not to download another one. Do not add third-party driver managers either; Selenium Manager replaces them.

## Your first test[#](https://testingbot.com#your-first-test)

Create a `tests` folder and `tests/test_first.py`:

```python
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_web_form_title():
    driver = webdriver.Chrome()
    try:
        driver.get("https://www.selenium.dev/selenium/web/web-form.html")
        assert driver.title == "Web form"

        driver.find_element(By.ID, "my-text-id").send_keys("Selenium")
        driver.find_element(By.CSS_SELECTOR, "button[type='submit']").click()

        assert driver.find_element(By.ID, "message").text == "Received!"
    finally:
        driver.quit()
```

Run it from the project folder:

```bash
pytest -q
```

Chrome opens, fills in the text field, submits, and closes. pytest prints:

```
. [100%]
1 passed in 4.27s
```

## What just happened[#](https://testingbot.com#what-just-happened)

- **Discovery.** pytest looked for files named `test_*.py` and, inside them, functions named `test_*`. Name a file `first.py` and pytest silently ignores it; that is the most common "my test doesn't run" question.
- **`webdriver.Chrome()`** asked Selenium Manager for a driver, started Chrome and opened a WebDriver session.
- **`driver.get(url)`** navigated and waited for the page's load event. It does not wait for JavaScript that runs afterwards; chapter 3 deals with that.
- **`find_element(By.ID, ...)`** located one element. Chapter 2 covers every `By` strategy.
- **`try` / `finally`** makes sure `quit()` runs even when an assertion fails. Without it, every failing test leaves a Chrome process behind. Chapter 4 replaces this with a pytest fixture, which is the idiomatic way to do the same thing.

After a Chrome update, a teammate's suite fails with "This version of ChromeDriver only supports Chrome version 155". Selenium is 4.52. What is the right fix?

 Download chromedriver 157 and put it on the PATH. Pin Chrome to version 155 so it stops updating. Remove the old chromedriver from the PATH and let Selenium Manager resolve the matching driver.

A driver found on the PATH takes precedence over Selenium Manager, so a stale manual download causes exactly this error. Downloading a newer one only postpones the problem to the next Chrome update.

## Headless runs[#](https://testingbot.com#headless-runs)

On a CI server there is no screen, so browsers run headless. Pass options to the driver:

```python
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.add_argument("--window-size=1920,1080")
driver = webdriver.Chrome(options=options)
```

Always set the window size with headless Chrome. The default headless window is much smaller than your monitor, and responsive layouts can hide or overlap elements at that size, which produces failures you never see when the browser is visible. Chapter 4 turns headless into a `--headless` command-line switch so you do not edit code to change it.

## Useful pytest flags from day one[#](https://testingbot.com#useful-pytest-flags-from-day-one)

| Command | Does |
| --- | --- |
| `pytest -q` | quiet output, one character per test |
| `pytest -v` | one line per test with its full name |
| `pytest -x` | stop at the first failure |
| `pytest -k title` | run only tests whose name contains "title" |
| `pytest tests/test_first.py::test_web_form_title` | run one test |
| `pytest --lf` | rerun only the tests that failed last time |

The test works, but it has a weakness: it reads `#message` right after clicking submit. It passed because the click triggers a page load that the driver waits for. On a page that renders the message with JavaScript after a delay, the same line would fail. That is the subject of chapter 3; first, chapter 2 looks at how to find elements in a way that survives changes to the page.

[Previous · Chapter 1 Selenium Python Tutorial with pytest](https://testingbot.com/resources/courses/selenium-python) [Next · Chapter 3 Selenium locators in Python: the By API](https://testingbot.com/resources/courses/selenium-python/locators)

On this page

1. [Check your Python version](https://testingbot.com#check-your-python-version)
2. [Create a project and a virtual environment](https://testingbot.com#create-a-project-and-a-virtual-environment)
3. [Install Selenium and pytest](https://testingbot.com#install-selenium-and-pytest)
4. [No driver downloads: Selenium Manager](https://testingbot.com#no-driver-downloads-selenium-manager)
5. [Your first test](https://testingbot.com#your-first-test)
6. [What just happened](https://testingbot.com#what-just-happened)
7. [Headless runs](https://testingbot.com#headless-runs)
8. [Useful pytest flags from day one](https://testingbot.com#useful-pytest-flags-from-day-one)

Certification

This course has a free, hands-on certificate.

[How it works](https://testingbot.com/resources/courses/selenium-python/certification)
