Sunday, 31 January 2016

Selenium Python Automation Framework from Scratch: Complete Step-by-Step Project Guide

 



Introduction

Automation testing is an essential part of modern software development. As web applications become more complex, organisations need reliable automation frameworks to test functionality, improve test coverage and reduce repetitive manual testing.

Selenium WebDriver with Python is a popular combination for browser automation. However, writing individual Selenium scripts is not enough for large projects. Testers need a structured framework that supports reusable components, test data management, reporting, logging and maintainable test execution.

A well-designed Selenium Python automation framework helps teams organise test cases, reduce code duplication and integrate automated tests into continuous integration pipelines.

In this tutorial, we will build a practical Selenium Python automation framework from scratch using PyTest and the Page Object Model.

1. What Is an Automation Testing Framework?

An automation testing framework is a structured collection of guidelines, reusable components, libraries and utilities used to develop and execute automated test cases.

A Selenium Python framework may contain:

  • Selenium WebDriver for browser automation.

  • PyTest for test execution.

  • Page Object Model for organising page interactions.

  • Fixtures for browser setup and cleanup.

  • Excel or CSV files for test data.

  • Logging for execution details.

  • Reporting tools for test results.

  • Git for source code management.

  • Jenkins or GitHub Actions for CI/CD integration.

The objective is to create an organised and reusable testing solution rather than a collection of disconnected scripts.

2. Types of Selenium Automation Frameworks

Several framework approaches are commonly used in automation testing.

Framework TypeDescription
Linear frameworkSimple scripts written sequentially
Modular frameworkApplication functionality divided into modules
Data-driven frameworkTest data maintained separately from test logic
Keyword-driven frameworkActions represented through predefined keywords
Hybrid frameworkCombines multiple framework approaches
BDD frameworkUses business-readable scenarios and steps

A hybrid framework combining Page Object Model, PyTest fixtures and data-driven testing is a practical approach for many Python automation projects.

3. Technologies Required

We will use the following technologies:

  • Python 3.

  • Selenium WebDriver.

  • PyTest.

  • OpenPyXL for Excel-based test data, where needed.

  • PyTest HTML for reporting.

  • Python logging.

  • Git and GitHub for version control.

Install the core dependencies:

python -m pip install selenium pytest pytest-html openpyxl

Create a virtual environment:

python -m venv venv

Activate it on Windows:

venv\Scripts\activate

Selenium Manager can automatically manage compatible browser drivers in many current setups.

4. Designing the Framework Architecture

Before writing code, plan the framework structure.

A recommended project structure is:

selenium_python_framework/
│
├── pages/
│   ├── __init__.py
│   ├── base_page.py
│   ├── login_page.py
│   └── home_page.py
│
├── tests/
│   ├── __init__.py
│   ├── test_login.py
│   └── test_homepage.py
│
├── utilities/
│   ├── __init__.py
│   ├── config_reader.py
│   └── logger.py
│
├── testdata/
│   └── login_data.csv
│
├── reports/
│
├── logs/
│
├── conftest.py
├── pytest.ini
├── requirements.txt
└── README.md

Understanding the structure:

  • pages/: Contains page classes and web element interactions.

  • tests/: Contains test scenarios and assertions.

  • utilities/: Contains reusable helper functions.

  • testdata/: Stores non-sensitive test data.

  • reports/: Stores generated test reports.

  • logs/: Stores execution logs.

  • conftest.py: Manages shared PyTest fixtures.

  • pytest.ini: Configures PyTest execution.

5. Creating the Base Page Class

The Base Page class contains reusable Selenium operations.

Create pages/base_page.py:

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

class BasePage:

    def __init__(self, driver):
        self.driver = driver
        self.wait = WebDriverWait(driver, 10)

    def click(self, locator):
        element = self.wait.until(
            EC.element_to_be_clickable(locator)
        )
        element.click()

    def enter_text(self, locator, text):
        element = self.wait.until(
            EC.visibility_of_element_located(locator)
        )
        element.clear()
        element.send_keys(text)

    def get_text(self, locator):
        element = self.wait.until(
            EC.visibility_of_element_located(locator)
        )
        return element.text

    def is_visible(self, locator):
        return self.wait.until(
            EC.visibility_of_element_located(locator)
        ).is_displayed()

    def get_title(self):
        return self.driver.title

This class can be inherited by other page objects, reducing repeated browser interaction code.

6. Creating the Login Page Object

Create pages/login_page.py:

from selenium.webdriver.common.by import By
from pages.base_page import BasePage

class LoginPage(BasePage):

    USERNAME = (By.ID, "username")
    PASSWORD = (By.ID, "password")
    LOGIN_BUTTON = (By.ID, "login")
    ERROR_MESSAGE = (By.ID, "error")

    def enter_username(self, username):
        self.enter_text(self.USERNAME, username)

    def enter_password(self, password):
        self.enter_text(self.PASSWORD, password)

    def click_login(self):
        self.click(self.LOGIN_BUTTON)

    def login(self, username, password):
        self.enter_username(username)
        self.enter_password(password)
        self.click_login()

    def get_error_message(self):
        return self.get_text(self.ERROR_MESSAGE)

The login page class contains all the locators and methods associated with the login page.

The element IDs are illustrative and must be replaced with the actual application's locators.

7. Creating the Home Page Object

Create pages/home_page.py:

from selenium.webdriver.common.by import By
from pages.base_page import BasePage

class HomePage(BasePage):

    HEADING = (By.TAG_NAME, "h1")

    def get_heading(self):
        return self.get_text(self.HEADING)

    def is_displayed(self):
        return self.is_visible(self.HEADING)

This class provides reusable methods to verify the home page.

8. Creating Browser Fixtures in conftest.py

Fixtures manage browser creation and cleanup.

Create conftest.py:

import pytest
from selenium import webdriver

@pytest.fixture
def driver():
    browser = webdriver.Chrome()
    browser.maximize_window()

    yield browser

    browser.quit()

Each test using this fixture receives a fresh browser session. The quit() operation runs during fixture teardown, including when a test fails.

9. Managing Application Configuration

Application URLs and environment settings should not be hardcoded throughout test scripts.

Create utilities/config_reader.py:

import configparser
from pathlib import Path

CONFIG_PATH = (
    Path(__file__).resolve().parents[1]
    / "config.ini"
)

config = configparser.ConfigParser()
config.read(CONFIG_PATH)

BASE_URL = config["application"]["base_url"]

Create config.ini in the project root:

[application]
base_url = https://example.com

For a real project, use separate configuration for development, testing and staging environments. Keep secrets outside version control, preferably in environment variables or an approved secrets manager.

10. Creating the First Automation Test

Create tests/test_login.py:

from pages.login_page import LoginPage
from pages.home_page import HomePage
from utilities.config_reader import BASE_URL

def test_valid_login(driver):

    driver.get(BASE_URL + "/login")

    login_page = LoginPage(driver)

    login_page.login(
        "testuser",
        "testpassword"
    )

    home_page = HomePage(driver)

    assert home_page.is_displayed()

This test demonstrates how the test layer uses page objects to perform a login workflow and verify the resulting page.

The URL, credentials and page locators are placeholders. Use a dedicated test application and valid test accounts when implementing the example.

11. Adding Data-Driven Testing

A framework should support multiple test scenarios without duplicating test code.

PyTest parameterization provides a simple solution:

import pytest

@pytest.mark.parametrize(
    "username,password,expected",
    [
        ("validuser", "valid123", "success"),
        ("invaliduser", "wrong123", "error"),
        ("validuser", "wrong123", "error")
    ]
)
def test_login_scenarios(
    driver,
    username,
    password,
    expected
):
    # Navigate to the application,
    # perform login and verify expected result.
    assert expected in ["success", "error"]

For a production implementation, connect each scenario to the login page object and verify the actual application result against the expected outcome.

For larger test datasets, Excel, CSV or JSON files can be used.

12. Implementing Logging

Logging helps testers understand what happened during test execution.

Create utilities/logger.py:

import logging
from pathlib import Path

LOG_DIR = Path("logs")
LOG_DIR.mkdir(exist_ok=True)

logging.basicConfig(
    filename=LOG_DIR / "automation.log",
    level=logging.INFO,
    format="%(asctime)s - %(levelname)s - %(message)s"
)

logger = logging.getLogger(__name__)

Use logging inside test scripts:

from utilities.logger import logger

def test_application():
    logger.info("Starting application test")

    assert True

    logger.info("Application test completed")

For a larger framework, configure logging handlers and log levels centrally, and avoid recording passwords or other sensitive information.

13. Generating Automation Test Reports

Install the reporting plugin:

python -m pip install pytest-html

Execute the test suite:

pytest --html=reports/report.html --self-contained-html

An HTML report can display:

  • Total tests executed.

  • Passed test cases.

  • Failed test cases.

  • Skipped test cases.

  • Execution duration.

  • Error details.

Reports are useful for reviewing automation results and communicating test status to project stakeholders.

14. Running Tests Using PyTest Configuration

Create pytest.ini:

[pytest]
testpaths = tests
python_files = test_*.py
python_functions = test_*
addopts = -v

Now execute the framework using:

pytest

Run only a particular test:

pytest tests/test_login.py

Run tests marked as smoke tests:

pytest -m smoke

Custom markers should first be registered in the configuration file to avoid warnings.

15. Integrating Selenium Python with Git and Jenkins

A professional automation framework should be version-controlled and capable of running in a CI/CD pipeline.

Git and GitHub

Git helps manage changes to test scripts, page objects and configuration. GitHub provides a platform for collaboration and code review.

Common commands:

git init
git add .
git commit -m "Initial automation framework"

Jenkins integration

A Jenkins pipeline can:

  1. Retrieve the automation project from Git.

  2. Set up Python.

  3. Install dependencies.

  4. Execute PyTest.

  5. Generate HTML reports.

  6. Publish test results.

Example shell execution:

python -m pip install -r requirements.txt
pytest --html=reports/report.html --self-contained-html

For CI environments, configure the browser and operating system dependencies appropriately. Headless execution can be used where a graphical browser display is unavailable.

16. Best Practices for Framework Development

  1. Follow a consistent project structure.

  2. Apply Page Object Model appropriately.

  3. Use reusable fixtures and utilities.

  4. Separate test data from test scripts.

  5. Use explicit waits for dynamic elements.

  6. Keep test cases independent.

  7. Maintain clear logging and reporting.

  8. Store configuration separately from application logic.

  9. Avoid committing passwords and secrets.

  10. Use Git for version control.

  11. Integrate automation into CI/CD.

  12. Review and maintain flaky tests regularly.

A framework should remain simple enough for the team to understand while providing the features required by the project.

17. Career Opportunities in Selenium Python Framework Development

Framework development is an important step in progressing from basic automation scripting to advanced automation engineering.

Relevant career roles include:

  • Automation Test Engineer.

  • Python Automation Tester.

  • Selenium Framework Developer.

  • QA Automation Engineer.

  • Software Development Engineer in Test (SDET).

  • Test Automation Lead.

Candidates should be able to explain framework architecture, fixtures, Page Object Model, data-driven testing, reporting and CI/CD integration.

Learn Selenium Python Automation Testing with Palium Skills

Palium Skills offers practical Automation Testing training for freshers, graduates, manual testers and working professionals.

The Selenium Python learning pathway can include:

  • Python programming fundamentals.

  • Selenium WebDriver.

  • Locators and web element handling.

  • PyTest framework.

  • Page Object Model.

  • Data-driven automation testing.

  • Framework development from scratch.

  • Logging and reporting.

  • Git, Jenkins and CI/CD fundamentals.

  • Real-time automation projects.

  • Interview preparation.

Training modes include classroom sessions at South Kolkata and Salt Lake, Kolkata, and instructor-led live online sessions for learners across India.

Contact Palium Skills

South Kolkata Centre: 1st Floor, Sheeba Bhavan, 1/22 Poddar Nagar, Near South City Mall, Kolkata – 700068.

Salt Lake Centre: 5th Floor, RDB Boulevard, Block GP, Salt Lake Electronic Complex, Kolkata – 700091.

Frequently Asked Questions

1. What is a Selenium Python automation framework?

It is a structured testing solution built using Selenium and Python, with reusable components for browser automation, test execution, reporting and data management.

2. Which testing framework is commonly used with Selenium Python?

PyTest is a popular choice because of its fixtures, parameterization, assertions and plugin ecosystem.

3. What is the Page Object Model?

POM is a design pattern in which application pages are represented by classes containing their locators and reusable interaction methods.

4. Can Selenium Python frameworks support data-driven testing?

Yes. They can use Excel, CSV, JSON, databases and PyTest parameterization to execute multiple test scenarios.

5. Can Selenium Python be integrated with Jenkins?

Yes. Jenkins can execute PyTest scripts as part of a CI/CD pipeline and publish the generated test reports.

6. Is Python suitable for large automation frameworks?

Yes. Python can support large automation projects when the framework is properly designed, modularised and maintained.

7. What should I learn after building a Selenium Python framework?

You can progress to API automation, Playwright, Docker, CI/CD, advanced reporting, cloud browser execution and test architecture.

No comments:

Post a Comment

TDS on Salary: A Practical Guide for HR and Payroll Professionals

  TDS on Salary: A Complete Guide for HR and Payroll Professionals Learn how TDS on salary works in India , the role of employers, employee...