Free tools Windows power users keep installed
One-click scans. No signup required.
Behave reads Gherkin feature files and maps their steps to Python functions; Selenium WebDriver performs the browser interactions those functions need. Together they let a team express a user-visible behavior in readable scenarios and verify it in a real browser. BDD is the collaborative practice of defining expected behavior—not a synonym for browser automation.
This tutorial builds a small sign-in test, from environment setup through cleanup and troubleshooting. Documentation versions are time-sensitive: Behave’s landing page is labeled 1.4.0.dev0, while its stable tutorial is identified as 1.3.3; Selenium’s Python API page is labeled 4.50.0 and lists Python 3.10+ support. See the Behave documentation, stable Behave tutorial, and Selenium Python API for current project guidance.
How Behave and Selenium fit together
A Behave feature file contains scenarios written in Gherkin, using steps such as Given, When, and Then. Behave finds Python functions whose decorators match those step phrases and runs them. Those functions can call Selenium WebDriver directly, or call page-object methods that encapsulate browser details.
BDD is intended to help developers, QA, and business participants collaborate on expected behavior. A scenario should explain what a user-relevant outcome is, not enumerate every click and selector. Selenium is one possible implementation layer for checking that behavior in a browser.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →#1 Best Overall
Install the tools and prepare a browser
-
Use Python 3.10 or newer, which the Selenium Python API currently lists as supported. Create and activate an isolated environment:
python -m venv .venv # macOS or Linux source .venv/bin/activate # Windows PowerShell .venvScriptsActivate.ps1 -
Install Behave and Selenium:
python -m pip install behave python -m pip install -U selenium -
When repeatability matters, record the versions resolved in your project dependency file (for example, with
python -m pip freeze) and install from that file in CI. The cited documentation does not specify a tested compatible Behave/Selenium version pair, so verify your chosen dependencies in your own environment rather than assuming one. -
Install a browser you intend to test. Selenium Manager generally manages driver setup when WebDriver is instantiated, reducing the need to download and configure a driver manually; the browser itself still needs to be available, and proxies, permissions, browser versions, or restricted CI environments can still require setup. Selenium documents support for Chrome, Edge, Firefox, Safari, WebKitGTK, and WPEWebKit.
Create the feature and project structure
Behave’s conventional minimum is a features/ directory containing feature files and a steps/ directory containing Python implementations. Add an environment hook and page module as the example grows:
Rank #2
project/
features/
login.feature
environment.py
steps/
login_steps.py
pages/
login_page.py
In features/login.feature, describe the expected result rather than the sequence of browser mechanics:
Feature: Account sign in
Scenario: A registered user reaches their account
Given a registered user is ready to sign in
When they submit valid credentials
Then their account page is displayed
The phrases after Given, When, and Then are matched to decorated Python functions. Behave also supports parameterized steps, data tables, text blocks, and Scenario Outlines for running one behavior against multiple example rows; use those when they make the behavior clearer, not merely to compress a UI script.
Start and stop the WebDriver reliably
Behave loads features/environment.py for lifecycle hooks. This example creates a fresh browser for each scenario and always closes it, including when a scenario fails:
# features/environment.py
from selenium import webdriver
def before_scenario(context, scenario):
context.driver = webdriver.Chrome()
def after_scenario(context, scenario):
driver = getattr(context, "driver", None)
if driver is not None:
driver.quit()
Constructing the driver in a hook gives step functions a shared context.driver. A fresh driver per scenario provides stronger isolation from cookies, tabs, and other browser state, at the cost of launching a browser repeatedly. A browser shared for an entire run can reduce startup overhead, but scenarios may then leak state into one another. Choose intentionally. Behave’s Selenium examples also show fixture-based lifecycle management and run-level setup/teardown; whichever scope you choose, ensure teardown calls quit().
Put locators and waiting in a page object
Page objects keep selectors and browser operations out of the behavior prose and make step functions easier to read. Adapt the URLs, selectors, and credentials below to an application and test environment you control; the example is a template, not a working test against a public sign-in page.
# features/pages/login_page.py
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
class LoginPage:
def __init__(self, driver, base_url):
self.driver = driver
self.base_url = base_url
def open(self):
self.driver.get(f"{self.base_url}/login")
def sign_in(self, email, password):
self.driver.find_element(By.ID, "email").send_keys(email)
self.driver.find_element(By.ID, "password").send_keys(password)
self.driver.find_element(By.CSS_SELECTOR, "button[type='submit']").click()
def account_heading(self):
heading = WebDriverWait(self.driver, 10).until(
EC.visibility_of_element_located((By.CSS_SELECTOR, "[data-testid='account-heading']"))
)
return heading.text
The explicit wait waits up to ten seconds for the account heading to become visible, then returns its text. Replace the selectors with stable attributes from your application, ideally ones maintained for testing, and use an assertion in the step implementation so the page object returns observed values rather than embedding scenario-specific expectations.
Connect the Gherkin steps to the page object
# features/steps/login_steps.py
import os
from behave import given, when, then
from features.pages.login_page import LoginPage
@given("a registered user is ready to sign in")
def registered_user_ready(context):
context.login_page = LoginPage(
context.driver,
os.environ["APP_BASE_URL"],
)
context.login_page.open()
context.email = os.environ["TEST_USER_EMAIL"]
context.password = os.environ["TEST_USER_PASSWORD"]
@when("they submit valid credentials")
def submit_valid_credentials(context):
context.login_page.sign_in(context.email, context.password)
@then("their account page is displayed")
def account_page_is_displayed(context):
heading = context.login_page.account_heading()
assert heading == "Your account", f"Unexpected account heading: {heading!r}"
Set APP_BASE_URL, TEST_USER_EMAIL, and TEST_USER_PASSWORD in the test environment before running. Keep secrets out of feature files and source control. The package import shown assumes the project root is on Python’s import path; if your package layout differs, adjust the import or use a package structure that Python can resolve.
Run the scenario and read the result
From the project root, run:
behave
Behave discovers feature files beneath features/, loads Python files in features/steps/, and reports each scenario as it executes. A passing scenario means the steps completed and assertions held; a failure report identifies the step where an exception or failed assertion occurred. Run a single feature during development with behave features/login.feature.
Choose the right test layer and keep scenarios maintainable
A browser test is useful when the behavior depends on the integrated front end: navigation, rendering, browser-side validation, or the user’s end-to-end path. It is not automatically the best way to verify every business rule. Behave’s practical guidance notes that testing a model or business-logic layer, such as a REST API, is often preferable when that is the behavior under test.
- Model or API layer: use when the rule can be checked without rendering a page; the feature can stay technology-agnostic and avoid browser state.
- Browser UI: reserve for representative user journeys or browser-specific behavior. Keep selectors and interaction details in Python helpers or page objects.
- Scenario wording: prefer “the account page is displayed” over instructions such as “click the blue button and find the third div.” Detail-heavy scenarios describe implementation and tend to change with the interface.
These are design trade-offs, not published speed or maintenance benchmarks. Pick the lowest layer that genuinely verifies the intended behavior, then retain browser scenarios for the integrated experience that lower-layer checks cannot establish.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Wait for conditions instead of sleeping
Fixed delays such as time.sleep(5) pause for the same interval whether the page is ready immediately or still loading afterward. An explicit wait for a specific observable condition is more targeted. The example page object waits for visibility of the account heading, but other conditions can be appropriate, such as presence of an element or a URL change.
Use one synchronization strategy consistently. Behave’s page-object guidance warns that combining Selenium’s implicit wait with WebDriverWait can make waits stack and create unpredictable timeouts. Do not add driver.implicitly_wait() to this explicit-wait example.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Best Value
Troubleshoot common failures
- Behave reports an undefined step: check that the wording in the feature file matches a decorated function, that the function is in
features/steps/, and that the Python file imports without an error. - Python cannot import a page module: verify the project root and package layout. Add appropriate
__init__.pyfiles if you are treating directories as packages, or adjust the import to match your structure. - Driver or browser startup fails: confirm the browser is installed and runnable by the current user. Check environment restrictions, browser compatibility, network access, and Selenium Manager’s ability to obtain or locate a driver; use a manually specified driver if your environment requires it.
- The test times out waiting for the heading: confirm the test reached the expected page, that the selector matches the current DOM, and that the account heading is actually visible only after successful authentication. Check credentials and application logs before increasing the timeout.
- Scenarios pass alone but fail in a suite: look for shared browser state, test data reused across scenarios, or cleanup that did not run. Isolate scenarios with fresh drivers or reset state explicitly.
- Timeouts seem longer or inconsistent: avoid mixing implicit and explicit waits. Wait for the specific browser condition needed and review whether navigation or application behavior itself is stalled.
- Credentials are missing: set the environment variables in the shell or CI secret store before invocation; do not put production credentials in the repository.
Or skip the browser setup
If your goal is a website screenshot rather than an interactive Behave scenario, ScreenshotNeo provides a screenshot API and MCP server. One GET request captures a URL; see the API documentation for parameters and response details.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo accepts cookie or consent banners like a visitor and removes 60+ known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, with response headers indicating the page verdict and billing status. Its MCP server offers take_screenshot, get_page_info, and capture_pdf for AI agents and MCP clients. The free plan includes 1,000 shots per month without a card; paid plans start at $5 for 3,000 shots.
Sign up for ScreenshotNeo’s free plan to get started.
Frequently Asked Questions
Can Behave test APIs as well as browser interfaces?
Yes. Behave’s scenario-and-step structure can exercise a model or API layer; use Selenium only when browser behavior is part of what you need to verify.
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 matchDoes Selenium Manager mean I do not need a browser installed?
No. It helps manage the browser driver, but the browser itself must be present and runnable in your environment.
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.




