Skip to content

QA-Automation-Starter/qa-automation-python

QA Automation for Python

Build Release
utils commons rest webdriver
License: Apache 2.0
Open in GitHub Codespaces Open in Dev Container

Modular Python packages for maintainable, BDD-style automated tests with pytest, Hamcrest, Allure reporting, and configurable logging.

Technology-agnostic; example REST and Selenium implementations included.


πŸ“¦ Project Structure

qa-automation-python/
β”œβ”€β”€ qa-testing-utils/        # Shared low-level utility functions
β”œβ”€β”€ qa-pytest-commons/       # Technology-agnostic test infrastructure
β”œβ”€β”€ qa-pytest-rest/          # REST-specific steps and config
β”œβ”€β”€ qa-pytest-webdriver/     # Selenium-specific implementation
β”œβ”€β”€ qa-pytest-template/      # Cookiecutter project template
β”œβ”€β”€ qa-pytest-examples/      # Usage examples for application test projects
β”œβ”€β”€ pyproject.toml           # Root environment definition for PDM
└── .vscode/                 # Recommended settings for VSCode integration

Architecture

Support for additional technologies, e.g. RabbitMQ, can be added by sub-classing these classes and adding specific steps, setup/teardown, and configuration. This allows reusing the basic configuration, reporting, logging, and retrying mechanisms. Further, application tests, steps, and configurations reuse by subclassing from technologies.

flowchart TD
    A[Tests: Define BDD scenarios as series of steps, also define specific setup and teardown] --> |contains| B[Steps: encapsulate UI or API operations and verifications, and may be composed of other steps]
    B --> |contains| C[Configurations: can be per environment, such as dev, qa, staging, and contain URLs, users, authentication schemes, encryption, etc.]
    B --> |uses| D[Matchers: Hamcrest matchers for single objects or for iterables]
    A --> |contains| C
    B --> |uses| E[Models: domain objects]

    subgraph Inheritance
        A1[GenericTests] -.-> |inherits| A2[Tests]
        B1[GenericSteps] -.-> |inherits| B2[Steps]
        C1[AbstractConfiguration] -.-> |inherits| C2[Configuration]
    end
Loading

Extending the Framework

To add support for a new technology (e.g., messaging, database), create:

  • MyTechConfiguration(BaseConfiguration)
  • MyTechSteps(GenericSteps[MyTechConfiguration])
  • MyTechTests(AbstractTestsBase[MyTechSteps, MyTechConfiguration]) This pattern ensures you reuse the core BDD, configuration, and reporting mechanisms.
classDiagram
    %% Core Abstractions
    class AbstractTestsBase {
        <<abstract>>
        +steps
        +_configuration
        +setup_method()
        +teardown_method()
    }
    class GenericSteps {
        <<abstract>>
        +given
        +when
        +then
        +and_
        +with_
        +retrying()
        +eventually_assert_that()
    }
    class BaseConfiguration {
        <<abstract>>
        +parser
    }

    %% Technology-Specific Extensions
    class RestTests
    class RestSteps
    class RestConfiguration

    class SeleniumTests
    class SeleniumSteps
    class SeleniumConfiguration

    %% Example: Custom Extension
    class TerminalXTests
    class TerminalXSteps
    class TerminalXConfiguration

    %% Relationships
    AbstractTestsBase <|-- RestTests
    AbstractTestsBase <|-- SeleniumTests
    SeleniumTests <|-- TerminalXTests

    GenericSteps <|-- RestSteps
    GenericSteps <|-- SeleniumSteps
    SeleniumSteps <|-- TerminalXSteps

    BaseConfiguration <|-- RestConfiguration
    BaseConfiguration <|-- SeleniumConfiguration
    SeleniumConfiguration <|-- TerminalXConfiguration

    RestTests o-- RestSteps : uses
    RestTests o-- RestConfiguration : configures

    SeleniumTests o-- SeleniumSteps : uses
    SeleniumTests o-- SeleniumConfiguration : configures

    TerminalXTests o-- TerminalXSteps : uses
    TerminalXTests o-- TerminalXConfiguration : configures

    %% Example extension note
    %% You can add new technologies by subclassing the three core abstractions:
    %% AbstractTestsBase, GenericSteps, and BaseConfiguration.
Loading

Key Classes (with links to source code):

Class Description Source
AbstractTestsBase Base for all test scenarios; holds steps and config abstract_tests_base.py
GenericSteps Base for all step implementations; provides BDD keywords generic_steps.py
BaseConfiguration Base for all configuration objects base_configuration.py
RestTests REST-specific test base rest_tests.py
RestSteps REST-specific steps rest_steps.py
RestConfiguration REST-specific configuration rest_configuration.py
SeleniumTests Selenium-specific test base selenium_tests.py
SeleniumSteps Selenium-specific steps selenium_steps.py
SeleniumConfiguration Selenium-specific configuration selenium_configuration.py
TerminalXTests Example: custom UI test base terminalx_tests.py
TerminalXSteps Example: custom UI steps terminalx_steps.py
TerminalXConfiguration Example: custom UI configuration terminalx_configuration.py

πŸš€ Quick Start (Locally with PDM)

Open in Codespace or Dev Container and everything will get installed and configured, otherwise:

  1. Install Python 3.13 on your system

  2. Install PDM:

    pipx install pdm[all]
  3. Install dependencies:

    pdm install
  4. Run all tests from the root:

    pdm run pytest

πŸ§ͺ Releasing

  1. branch
  2. commit changes
  3. pull request -- will trigger a build
  4. build succeeds --> tag with vX.X.X, e.g. v1.2.3 -- will trigger a release
  5. verify new versions appeared on https://pypi.org/

πŸ— Adding a New Package

cd qa-automation-python
pdm plugin add pdm-init  # if not already available
pdm init  # or copy an existing module like qa-testing-utils

Then edit pyproject.toml accordingly.


Reports

  1. report.html is generated in the root folder; just open it in a browser
  2. allure-results/ is generated for Allure reporting (requires Allure server). To view Allure reports, install Allure and run:
    allure serve allure-results/

Example Tests

Below are example test cases demonstrating BDD-style usage with this framework:

# Example: UI search test
# (Assumes self.login_section and self._configuration.users are defined)
def should_find(self):
    self.login_section(random.choice(self._configuration.users))
    for word in ["hello", "kitty"]:
        (self.steps
            .when.searching_for(word)
            .then.the_search_hints(
                yields_item(contains_string_ignoring_case(word))))
# Example: API add test
def should_add(self):
    random_pet = SwaggerPetstorePet.random()
    (self.steps
        .when.adding(random_pet)
        .then.the_available_pets(yields_item(is_(random_pet))))

Requirements

  • Python 3.13
  • Google Chrome for local Selenium testing
  • PDM (Python package manager)

TODO
  • Add browser matrix support (Firefox, Safari, Edge)
  • Make the BDD intro words appear in Allure report
  • Extend test examples (API + UI)

βœ… License

This project is licensed under the Apache 2.0 License.

About

No description, website, or topics provided.

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Packages

No packages published

Languages