5 Best Ways to Trigger Headless Test Execution in Selenium with Python

πŸ’‘ Problem Formulation: You want to run Selenium tests without opening a browser UI to save resources, execute tests faster, and integrate into a CI/CD pipeline. The input is your test script in Python using Selenium, and the desired output is the test results after executing the script in a headless mode.

Method 1: Using Options Class in Selenium

Headless browser testing can be easily triggered in Selenium with Python by configuring the browser options to run in headless mode. For browsers like Chrome and Firefox, the Options class includes a method to define headless as a browser argument, directing it to run without the GUI component.

Here’s an example:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options()
chrome_options.add_argument("--headless")
driver = webdriver.Chrome(options=chrome_options)
driver.get("http://example.com")
print(driver.title)
driver.quit()

The output will be the title of the “http://example.com” webpage, shown in the console rather than a browser UI.

This code creates an instance of the Chrome web driver with ‘headless’ argument. The Chrome driver then navigates to “http://example.com”, retrieves the page title without opening a GUI, and prints it to the console before closing the browser session.

Method 2: Environment Variables to Control Browser Mode

Setting environment variables can govern whether a test runs in headless mode, offering a flexible switch between headless and GUI test execution. Python can read these variables and adjust the Selenium options accordingly, making it suitable for different stages of development and testing.

Here’s an example:

import os
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options()
if os.getenv('HEADLESS') == '1':
    chrome_options.add_argument('--headless')

driver = webdriver.Chrome(options=chrome_options)
driver.get("http://example.com")
print(driver.title)
driver.quit()

The output will again be the title of the webpage fetched, contingent on the environment variable ‘HEADLESS’ being set to ‘1’.

This code snippet checks for an environment variable ‘HEADLESS’. If this variable is set, it triggers headless execution. This method provides an external control over test mode without altering the codebase.

Method 3: Setting Headless Mode as WebDriver Default

In cases where headless execution is the norm, setting this mode as the default for the WebDriver object might be a good idea. This can reduce redundancy in the code if you’re writing multiple test scripts that all need to run headless.

Here’s an example:

from selenium.webdriver import Firefox, FirefoxOptions

options = FirefoxOptions()
options.add_argument('-headless')

def create_webdriver_instance():
    return Firefox(options=options)

driver = create_webdriver_instance()
driver.get('http://example.com')
print(driver.title)
driver.quit()

The output is the title of “http://example.com” with no visible browser window.

The given Python function create_webdriver_instance() sets up a Firefox WebDriver with the headless argument by default, simplifying the construction of a headless driver for subsequent test scripts that call this function.

Method 4: Using a WebDriver Wrapper for Headless Execution

Utilizing a wrapper for WebDriver interactions can encapsulate the headless configuration, making scripts more readable and reducing boilerplate code. A custom wrapper class can be created that always initiates the browser in headless mode unless specified otherwise.

Here’s an example:

from selenium import webdriver

class HeadlessWebDriver:

    def __init__(self, browser_type='chrome', headless=True):
        if browser_type.lower() == 'chrome':
            options = webdriver.ChromeOptions()
            if headless:
                options.add_argument('--headless')
            self.driver = webdriver.Chrome(options=options)

    def get_title(self, url):
        self.driver.get(url)
        return self.driver.title

# Usage
webdriver_instance = HeadlessWebDriver()
print(webdriver_instance.get_title('http://example.com'))

This will output the title of “http://example.com” without rendering a browser window.

The HeadlessWebDriver class is initialized with a browser type and a flag determining if it should run in headless mode. This abstraction simplifies headless driver creation and usage across different browser types.

Bonus One-Liner Method 5: Using Pytest to Run Tests Headlessly

If you’re using Pytest for testing, you can integrate Selenium with it, and use a Pytest command-line option to run tests headlessly. This method is highly convenient for developers already working with Pytest.

Here’s an example:

pytest --headless test_module.py

The output is the test results in the terminal, and it’s implied that within the test script, the headless option is being handled based on this command-line argument.

This method assumes that the test script test_module.py is written to handle the “–headless” command-line argument to configure Selenium for headless execution.

Summary/Discussion

  • Method 1: Using Options Class. Strengths: Direct and widely supported. Weaknesses: Browser-specific implementation.
  • Method 2: Environment Variables. Strengths: Offers flexibility without modifying code. Weaknesses: Requires setting up environment variables externally.
  • Method 3: WebDriver Default. Strengths: Streamlines headless testing setup. Weaknesses: Less flexible if GUI mode is occasionally required.
  • Method 4: WebDriver Wrapper. Strengths: Encapsulates headless configuration. Weaknesses: Needs additional class setup; might be overly abstract for simple use cases.
  • Bonus Method 5: Pytest Integration. Strengths: Integrates with a testing framework; simple CLI usage. Weaknesses: Depends on Pytest; less explicit in code.