A comprehensive testing framework built with Python and Pytest for API testing and database operations using PostgreSQL.
This project provides a robust framework for testing REST APIs and PostgreSQL database operations. It combines API client utilities with database connection management, following Python best practices and Pytest conventions.
- API Testing: Client abstraction for REST API endpoints (GET, POST, PUT, DELETE)
- Database Operations: Connection pooling and utility methods for PostgreSQL interactions
- Test Fixtures: Reusable Pytest fixtures for API client and database connections
- Type Hints: Full type annotations for better IDE support and code clarity
- Docker Support: Pre-configured PostgreSQL container with initialization scripts
- Error Handling: Comprehensive error handling and logging throughout the framework
pytest-api-framework/
βββ api-framework/
β βββ src/
β β βββ __init__.py
β β βββ api_client.py # REST API client abstraction
β β βββ api_endpoints.py # API endpoint definitions
β β βββ database.py # PostgreSQL connection management
β βββ tests/
β β βββ conftest.py # Pytest fixtures and configuration
β β βββ test_db_connection.py # Database tests
β β βββ test_activities.py # API endpoint tests
β β βββ data/
β β βββ activities.py # Test data definitions
β βββ reports/ # Generated test reports
β βββ requirements.txt # Python dependencies
β βββ pytest.ini # Pytest configuration
βββ docker/
β βββ docker-compose.yml # PostgreSQL container setup
β βββ init.sql # Database initialization script
βββ README.md
Provides a simple abstraction for HTTP operations:
APIClient.get()- Retrieve dataAPIClient.post()- Create resourcesAPIClient.put()- Update resourcesAPIClient.delete()- Remove resources
Supports URL path parameters and query strings.
Manages PostgreSQL connections with connection pooling:
execute_query()- Fetch multiple rows as tuplesexecute_query_one()- Fetch a single rowexecute_query_dict()- Fetch rows as dictionariesexecute_update()- Insert, update, or delete operationsexecute_many()- Batch operations- Context manager support for safe connection handling
Features:
- Connection pooling (SimpleConnectionPool)
- Automatic commit/rollback
- SQL injection prevention via parameterized queries
- Type hints and comprehensive docstrings
Reusable test fixtures:
api_client- Pre-configured REST API client (module scope)db_connection- PostgreSQL connection instance (module scope)
- Docker and Docker Compose installed
- No need to install PostgreSQL locally
- Start the PostgreSQL Container
cd docker
docker-compose up -dThis will:
- Create a PostgreSQL container with credentials:
- User:
user - Password:
1234 - Database:
testdb - Port:
5432
- User:
- Initialize the database with sample data from
init.sql
- Verify the Container is Running
docker-compose ps- Access the Database (optional)
docker-compose exec db psql -U user -d testdbThe initialization script (docker/init.sql) creates the following table:
CREATE TABLE people (
id SERIAL PRIMARY KEY,
fname VARCHAR(100),
age INT
);Sample Data:
id | fname | age
---|---------|-----
1 | Alice | 30
2 | Bob | 25
3 | Charlie | 35
Update tests/conftest.py with your PostgreSQL credentials:
@pytest.fixture(scope="module")
def db_connection():
db = DatabaseConnection(
host="localhost", # Change if Docker is on different host
database="testdb", # Match POSTGRES_DB from docker-compose.yml
user="user", # Match POSTGRES_USER from docker-compose.yml
password="1234", # Match POSTGRES_PASSWORD from docker-compose.yml
port=5432
)
yield db
db.close()# Stop the container
docker-compose down
# Remove the container and volumes
docker-compose down -vpip install -r requirements.txtKey Dependencies:
pytest- Testing frameworkrequests- HTTP client librarypsycopg2-binary- PostgreSQL adapter for Pythonmypy- Static type checkerpytest-reporter-html1- HTML test report generation
# Run all tests
pytest
# Run with verbose output
pytest -v
# Run with print statements visible
pytest -s -v
# Run specific test file
pytest tests/test_db_connection.py
# Generate HTML report
pytest --html=reports/html1-report.htmlEnsure the Docker container is running before executing database tests:
# Start PostgreSQL
cd docker && docker-compose up -d && cd ..
# Run database tests
pytest tests/test_db_connection.py -vdef test_users(db_connection):
# Query the database
people = db_connection.execute_query_dict(
"SELECT * FROM people WHERE id = %s",
(1,)
)
# Validate results
assert len(people) > 0
person = people[0]
assert person["fname"] == "Alice"
assert person["age"] == 30def test_get_activity(api_client):
response = api_client.get(Endpoints.ACTIVITIES_BY_ID, id=1)
assert response.status_code == 200- Parameterized Queries: Always use
%splaceholders to prevent SQL injection - Connection Management: Use context managers (
withstatements) for safe connection handling - Fixtures: Leverage Pytest fixtures for setup and teardown
- Type Hints: Use type annotations for better code documentation
- Error Handling: Catch and log errors appropriately
- Test Isolation: Each test should be independent and repeatable
- Async Support: For I/O-bound tests, consider using
pytest-asyncio
See requirements.txt for the complete list. Key dependencies:
| Package | Version | Purpose |
|---|---|---|
| pytest | Latest | Testing framework |
| requests | Latest | HTTP client |
| psycopg2-binary | Latest | PostgreSQL adapter |
| mypy | Latest | Type checking |
| pytest-reporter-html1 | Latest | HTML reports |
- Verify Docker container is running:
docker-compose ps - Check credentials in
conftest.pymatchdocker-compose.yml - Ensure port 5432 is not in use:
lsof -i :5432
- Activate virtual environment:
source venv/bin/activate - Reinstall dependencies:
pip install -r requirements.txt
- Use
-vflag for verbose output - Use
-sflag to see print statements - Check database initialization:
docker-compose logs db
This project is open source and available under the MIT License.
AlexAlexandreAlves
Happy Testing! π§ͺ