A production-ready test automation framework built with Playwright + Python, designed for modern web applications with comprehensive UI, API, and database testing capabilities.
- π― Complete testing solution: UI, API, and Database testing in one framework
- β‘ Fully async: Built with async/await for optimal performance
- οΏ½ Flexible configuration: Environment-based setup via
.envfiles - π Multi-browser support: Chromium, Firefox, and WebKit
- οΏ½ Parallel execution: Auto-configured via
PYTEST_WORKERSenvironment variable - οΏ½ Smart screenshots: Automatic capture on test failures
- οΏ½ Docker ready: Full containerization support for CI/CD
- π§ Pre-commit hooks: Automated code quality checks (black, flake8, mypy, etc.)
- π Comprehensive docs: Detailed guides for UI, API, and database testing
- οΏ½ Modular design: Page Object Model with reusable components
- Python 3.10 or higher
- pip (Python package manager)
- Git
# 1. Clone the repository
git clone https://github.com/ErickFlores13/playwright-python-async-template.git
cd playwright-python-async-template
# 2. Create virtual environment
python -m venv venv
# 3. Activate virtual environment
# Windows
venv\Scripts\activate
# Linux/macOS
source venv/bin/activate
# 4. Install dependencies
pip install -r requirements.txt
# 5. Install Playwright browsers
playwright install
# 6. Configure environment
cp .env.example .env
# Edit .env with your settingsRun tests with Docker Compose for isolated environments with PostgreSQL and Redis:
# Run tests with all services (PostgreSQL + Redis)
docker-compose --profile with-db --profile with-redis up --abort-on-container-exit
# Run tests with PostgreSQL only
docker-compose --profile with-db up --abort-on-container-exit
# Run tests with Redis only
docker-compose --profile with-redis up --abort-on-container-exit
# Run tests without external services
docker-compose up --abort-on-container-exit
# Clean up containers and volumes
docker-compose down -vDocker Services Available:
playwright-tests: Main test runner containerpostgres: PostgreSQL 15 database (profile:with-db)redis: Redis 7 cache (profile:with-redis)
All services include health checks and automatic dependency management.
Edit .env with your basic settings:
# Required
BASE_URL=https://your-application.com
TEST_USERNAME=test_user
TEST_PASSWORD=test_password
# Optional - Browser configuration
BROWSER=chromium # chromium | firefox | webkit
HEADLESS=true # true | false
PYTEST_WORKERS=auto # auto | 1 | 2 | 4 | 8
# Optional - Enable database testing
DB_TEST=false # Set to true if needed# Run example tests
pytest tests/test_ui_examples.py -v
# Run with visible browser (debugging)
pytest tests/test_ui_examples.py --headed -v
# Run in parallel
pytest tests/ -n autoEnable automatic code quality checks before commits:
# Install pre-commit
pip install pre-commit
# Install the git hooks
pre-commit install
# Run manually on all files
pre-commit run --all-filesConfigured hooks:
- black - Code formatting (line length: 100)
- isort - Import sorting
- flake8 - Code linting
- mypy - Type checking
- bandit - Security checks
- pydocstyle - Docstring linting
- trailing-whitespace - File cleanup
- check-yaml/json - Config validation
- markdownlint - Markdown formatting
Pre-commit hooks run automatically on git commit and ensure consistent code quality across the team.
playwright-python-async-template/
βββ pages/ # Page Object Model
β βββ base_page.py # Core browser interactions
β βββ standard_web_page.py # Common UI patterns (CRUD, filters, etc.)
β βββ login_page.py # Authentication
β βββ examples/ # Example page objects
β
βββ helpers/ # Helper modules
β βββ api_client.py # API testing client
β βββ database.py # Database client (PostgreSQL, MySQL, etc.)
β βββ redis_client.py # Redis client
β
βββ utils/ # Utilities
β βββ config.py # Configuration management
β βββ consts.py # Constants and enums
β βββ exceptions.py # Custom exceptions
β βββ test_helpers.py # Test utilities
β
βββ tests/ # Test suites
β βββ test_ui_examples.py # UI testing examples
β βββ test_api_examples.py # API testing examples
β βββ test_database_examples.py # Database testing examples
β βββ test_crud_example.py # Complete CRUD example
β
βββ docs/ # Documentation
β βββ UI_TESTING.md # UI testing guide
β βββ API_TESTING.md # API testing guide
β βββ DATABASE_TESTING.md # Database testing guide
β
βββ ci/ # CI/CD configuration
β βββ Jenkinsfile # Jenkins pipeline
β
βββ conftest.py # Pytest configuration and fixtures
βββ pytest.ini # Pytest settings
βββ requirements.txt # Python dependencies
βββ Dockerfile # Docker configuration
βββ docker-compose.yml # Docker Compose orchestration
βββ .pre-commit-config.yaml # Pre-commit hooks configuration
βββ pyproject.toml # Python tooling configuration
βββ .env.example # Environment template
βββ README.md # This file
Comprehensive guides for each testing type:
-
UI Testing Guide - Complete guide for UI automation
- Page Object Model patterns
- Form handling and validations
- CRUD operations
- Advanced UI interactions
-
API Testing Guide - Complete guide for API testing
- Authentication methods (Bearer, API Key, Basic Auth)
- HTTP methods (GET, POST, PUT, PATCH, DELETE)
- File uploads/downloads
- Pagination and retry logic
- Performance testing
-
Database Testing Guide - Complete guide for database testing
- PostgreSQL, MySQL, SQL Server, Oracle support
- Direct queries and ORM usage
- Data validation patterns
- Redis integration
from pages.base_page import BasePage
@pytest.mark.asyncio
async def test_ui(page):
base_page = BasePage(page)
await page.goto("https://your-app.com")
await base_page.fill_data({
"#username": "test_user",
"#password": "test_pass"
})
await page.click("button[type='submit']")π See UI Testing Guide for complete examples
@pytest.mark.asyncio
async def test_api(api_client):
await api_client.set_bearer_token(os.getenv("API_BEARER_TOKEN"))
users = await api_client.get("/users")
assert len(users) > 0π See API Testing Guide for complete examples
@pytest.mark.asyncio
async def test_database(db_client):
user = await db_client.fetch_one(
"SELECT * FROM users WHERE email = :email",
{"email": "test@test.com"}
)
assert user["status"] == "active"οΏ½ See Database Testing Guide for complete examples
The framework uses environment variables for configuration. All settings are in .env:
# Application
BASE_URL=https://your-app.com
TEST_USERNAME=test_user
TEST_PASSWORD=test_pass
# Browser
BROWSER=chromium # chromium | firefox | webkit
HEADLESS=true # true | false
VIEWPORT_WIDTH=1920
VIEWPORT_HEIGHT=1080
# Test Execution
PYTEST_WORKERS=auto # auto | 1 | 2 | 4 | 8
TIMEOUT=30000
SCREENSHOT_ON_FAILURE=true# API Testing
API_BASE_URL=https://api.example.com
API_BEARER_TOKEN=your_token
# Database Testing
DB_TEST=false # Set to true to enable
DB_TYPE=postgresql # postgresql | mysql | mssql | oracle
DB_HOST=localhost
DB_PORT=5432
# Redis
REDIS_HOST=localhost
REDIS_PORT=6379See .env.example for all available options.
Generate beautiful test reports using Allure:
# Windows (Chocolatey)
choco install allure
# macOS (Homebrew)
brew install allure
# Linux (Snap)
sudo snap install allure --classicNote: The Allure results directory (
--alluredir=allure-results) is already configured inpytest.ini. You do not need to add it to your pytest command.
# Run your tests (no need to specify --alluredir)
pytest
# Generate HTML report
allure generate allure-results --clean -o allure-report
# Open the report in your browser
allure open allure-report# Build and run tests
docker build -t playwright-tests .
docker run --rm \
-e BASE_URL=https://your-app.com \
-e TEST_USERNAME=test_user \
-e TEST_PASSWORD=test_pass \
playwright-testsExample Jenkinsfile included in ci/Jenkinsfile.
Auto-configured via environment variable:
# .env
PYTEST_WORKERS=auto # Auto-detect CPU cores
# or
PYTEST_WORKERS=4 # Use 4 workers
# Run tests (parallel execution is automatic)
pytest tests/from pages.base_page import BasePage
class MyAppPage(BasePage):
def __init__(self, page):
super().__init__(page)
self.login_button = '[data-testid="login"]'
async def login(self, username, password):
await self.fill_data({
'#username': username,
'#password': password,
})
await self.page.click(self.login_button)@pytest.mark.asyncio
async def test_hybrid(page, api_client):
# UI login
await page.goto(f"{os.getenv('BASE_URL')}/login")
# ... perform login ...
# Extract token from UI
token = await page.evaluate("localStorage.getItem('token')")
# Use token for API testing
await api_client.set_bearer_token(token)
user_data = await api_client.get("/users/me")
# Verify UI and API data match
ui_username = await page.text_content(".username")
assert user_data["username"] == ui_usernameThe framework provides pytest markers for organizing and running specific test categories:
# Run only smoke tests
pytest -m smoke_test
# Run regression suite
pytest -m regression
# Run integration tests
pytest -m integration
# Run unit tests only
pytest -m unit
# Skip slow tests
pytest -m "not slow"
# Combine markers
pytest -m "smoke_test or regression"Available Markers:
| Marker | Description | Example Usage |
|---|---|---|
smoke_test |
Quick smoke tests for critical functionality | @pytest.mark.smoke_test |
regression |
Full regression test suite | @pytest.mark.regression |
integration |
Integration tests (UI + API + DB) | @pytest.mark.integration |
unit |
Unit tests for isolated components | @pytest.mark.unit |
slow |
Slow-running tests (e.g., long waits, bulk operations) | @pytest.mark.slow |
Usage Example:
import pytest
@pytest.mark.smoke_test
@pytest.mark.asyncio
async def test_login(page):
"""Critical smoke test for login functionality."""
# Test code here
pass
@pytest.mark.regression
@pytest.mark.slow
@pytest.mark.asyncio
async def test_bulk_data_processing(page):
"""Regression test with slow execution."""
# Test code here
passContributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes using Conventional Commits
- Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Built with Playwright
- Testing with pytest
- Reporting with Allure
- Documentation: Check the
docs/directory for detailed guides - Examples: See
tests/directory for working examples - Issues: GitHub Issues
Tests timing out?
- Increase
TIMEOUTin.env - Use
--headedmode to see what's happening
Browser not found?
playwright installImport errors?
# Windows (PowerShell)
$env:PYTHONPATH = "${pwd}"
# Linux/macOS
export PYTHONPATH="${PYTHONPATH}:$(pwd)"Made with β€οΈ by Erick Flores