Driver Instantiation
Create and configure Appium and Selenium driver instances for mobile and web test automation using Options classes
What is Driver Instantiation?
Driver instantiation is the process of creating a WebDriver session that connects your test code to the application under test. The driver is the bridge between your test scripts and the browser or mobile device — every interaction (tapping, typing, scrolling) goes through this driver instance.
In a typical test framework, two entry points are provided:
- Selenium WebDriver for web testing (browsers)
- Appium WebDriver for mobile testing (iOS and Android)
Both follow the same pattern: create an options/capabilities object, then pass it to a driver constructor that starts the automation session.
Prerequisites
Mobile Driver (Appium)
Android
from appium import webdriver
from appium.options import UiAutomator2Options
options = UiAutomator2Options()
options.platform_name = "Android"
options.device_name = "emulator-5554"
options.automation_name = "UiAutomator2"
options.app = "/path/to/app.apk"
driver = webdriver.Remote(
command_executor="http://127.0.0.1:4723",
options=options,
)
iOS
from appium import webdriver
from appium.options import XCUITestOptions
options = XCUITestOptions()
options.platform_name = "iOS"
options.device_name = "iPhone 15"
options.platform_version = "17.0"
options.automation_name = "XCUITest"
options.app = "/path/to/app.ipa"
driver = webdriver.Remote(
command_executor="http://127.0.0.1:4723",
options=options,
)
The server URL is
http://127.0.0.1:4723(no/wd/hubpath). The/wd/hubprefix was required in Appium 1.x but is no longer needed.
Web Driver (Selenium)
Chrome
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("--window-size=1920,1080")
driver = webdriver.Chrome(options=options)
Firefox
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
options = Options()
driver = webdriver.Firefox(options=options)
Headless Mode
For CI environments or when you do not need a visible browser:
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("--headless=new")
options.add_argument("--window-size=1920,1080")
options.add_argument("--disable-gpu")
Driver Architecture
The driver follows a layered architecture:
Test Code (test_login.py)
|
Page Object (LoginPage)
|
Framework Wrapper (AppiumBase / SeleniumBase)
|
Core Driver (appium.webdriver / selenium.webdriver)
|
Automation Server (Appium / Selenium Grid / ChromeDriver)
|
Application Under Test
- Core Driver — The Appium or Selenium WebDriver instance that manages the session
- Framework Wrapper — Optional wrapper classes (e.g.,
AppiumBase,SeleniumBase) that add convenience methods for common operations - Page Object — Classes that represent pages/screens and use the driver to interact with elements
- Test Code — Test functions that use page objects to verify behavior
The driver instantiation creates the Core Driver. Your page objects should receive this driver instance in their constructor.
Using Framework Wrappers
If your test framework provides wrapper classes around the core driver, the typical pattern is:
# create the core driver
from appium import webdriver
from appium.options import UiAutomator2Options
options = UiAutomator2Options()
options.platform_name = "Android"
options.device_name = "emulator-5554"
options.app = "/path/to/app.apk"
core_driver = webdriver.Remote(
command_executor="http://127.0.0.1:4723",
options=options,
)
# wrap it with the framework wrapper
from framework import AppiumBase
wrapped_driver = AppiumBase(core_driver)
# pass to page objects
from screens.login_screen import LoginScreen
login = LoginScreen(wrapped_driver)
The wrapper adds framework-specific functionality (custom waits, logging, screenshot capture) while the page objects remain driver-agnostic.
Driver Lifecycle
Setup and Teardown
Always clean up the driver session when tests complete:
import pytest
from appium import webdriver
from appium.options import UiAutomator2Options
@pytest.fixture
def driver():
options = UiAutomator2Options()
options.platform_name = "Android"
options.device_name = "emulator-5554"
options.app = "/path/to/app.apk"
driver = webdriver.Remote(
command_executor="http://127.0.0.1:4723",
options=options,
)
yield driver
driver.quit()
Session Scope
For performance, you can share a single driver session across multiple tests:
@pytest.fixture(scope="session")
def driver():
# driver is created once for the entire test session
...
yield driver
driver.quit()
Use session-scoped drivers carefully. Tests must not depend on state left by previous tests. Use
appium:noResetandappium:fullResetcapabilities to control app state between tests.
Good to Know
Remote Execution
To run tests against a remote Appium server or Selenium Grid, change the
command_executor URL:
driver = webdriver.Remote(
command_executor="http://remote-server:4723",
options=options,
)
Implicit vs Explicit Waits
After instantiating the driver, configure wait behavior:
# implicit wait (applies to all find_element calls)
driver.implicitly_wait(10)
# explicit wait (recommended -- wait for specific conditions)
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10)
element = wait.until(EC.presence_of_element_located((By.ID, "username")))
Prefer explicit waits over implicit waits. Mixing both can lead to unpredictable timeout behavior.
Troubleshooting
”Could not start a new session”
- Ensure the Appium server is running (
appiumin a separate terminal) - Verify the server URL matches your
command_executor - Check that the specified driver is installed (
appium driver list --installed)
“Connection refused” on Port 4723
The Appium server is not running or is running on a different port:
# start the Appium server
appium
# or on a specific port
appium --port 4724
“/wd/hub” Path Errors
If you see errors related to /wd/hub:
- Use
http://127.0.0.1:4723(no path suffix) - The
/wd/hubpath was only used in Appium 1.x and is no longer supported
Driver Quit Errors
If driver.quit() fails or hangs, the session may already be terminated. Wrap
cleanup in a try/except:
@pytest.fixture
def driver():
...
yield driver
try:
driver.quit()
except Exception:
pass
Resources
Official Appium guide for creating your first automation session
Official Selenium documentation for setting up and using WebDriver
Official Appium Python client library with API documentation and examples