Database Backend Testing
Audience: Contributors who want to understand how ActingWeb tests dual database backends.
Overview
ActingWeb supports two database backends:
DynamoDB - AWS DynamoDB with PynamoDB ORM
PostgreSQL - PostgreSQL 12+ with psycopg3
Both backends implement the same protocol interface, allowing applications to switch between them via configuration.
CI/CD Matrix Testing
Test Execution
Tests run in parallel using GitHub Actions matrix strategy:
matrix:
backend: [dynamodb, postgresql]
python-version: ['3.11']
Each backend is tested independently with:
1,023 total tests per backend
Same test suite for both backends (backend-agnostic)
Separate coverage reports uploaded with backend-specific flags
Test Results
Check runs: Two separate check runs appear in PR - one per backend
Artifacts: Separate test results and coverage reports for each backend
Summary: Automated PR comment shows status of both backends
Code Coverage Strategy
Why Patch Coverage Appears Low
When new backend code is added, patch coverage appears lower than actual because:
Mutually Exclusive Code Paths
PostgreSQL code only runs when
DATABASE_BACKEND=postgresqlDynamoDB code only runs when
DATABASE_BACKEND=dynamodbEach test run covers ~50% of database layer code
Backend-Specific Implementations
New PostgreSQL backend: ~2,400 lines
Only exercised in PostgreSQL test run
Appears as “uncovered” in DynamoDB test run
Combined Coverage Reporting
Codecov merges both backend reports
Total coverage = union of both test runs
Patch coverage calculation doesn’t account for mutually exclusive paths
Actual Coverage
Total Project Coverage: ~50% (union of both backends)
DynamoDB backend coverage: ~50% (when
DATABASE_BACKEND=dynamodb)PostgreSQL backend coverage: ~50% (when
DATABASE_BACKEND=postgresql)Core/shared code coverage: ~70% (covered by both backends)
Patch Coverage Interpretation:
24% patch coverage = ~50% of backend code is covered when that backend is active
Not a quality issue - reflects the dual backend architecture
Codecov Configuration
See codecov.yml for:
Backend flags: Separate
dynamodbandpostgresqlflagsComponent tracking: Separate components for each backend
Adjusted thresholds: Lower patch coverage target (20%) to account for backend exclusivity
Carryforward: Coverage persists between commits for unchanged code
Running Tests Locally
Test Both Backends
# DynamoDB (requires docker-compose)
docker-compose -f docker-compose.test.yml up -d dynamodb-test
DATABASE_BACKEND=dynamodb poetry run pytest tests/
# PostgreSQL (requires docker-compose)
docker-compose -f docker-compose.test.yml up -d postgres-test
cd actingweb/db/postgresql && poetry run alembic upgrade head && cd ../../..
DATABASE_BACKEND=postgresql poetry run pytest tests/
Backend-Specific Tests
# Run only DynamoDB-specific tests
poetry run pytest -m dynamodb
# Run only PostgreSQL-specific tests
poetry run pytest -m postgresql
Coverage Reports
View in Artifacts
After CI runs:
Go to Actions → Workflow run
Download artifacts:
coverage-report-dynamodbcoverage-report-postgresqltest-results-dynamodbtest-results-postgresql
View in Codecov
Codecov shows:
Overall coverage: Combined from both backends
Component coverage: Separate for DynamoDB and PostgreSQL
Flags: Filter by
dynamodborpostgresqlflag
Quality Assurance
Despite lower patch coverage percentage, quality is ensured by:
100% of tests passing for both backends
Protocol compliance tests verify both backends match interface
Integration tests exercise real database operations
Type checking with pyright (0 errors)
Linting with ruff (0 warnings)
Summary
The dual backend architecture means:
✅ Both backends fully tested (1,023 tests each)
✅ Same test suite ensures feature parity
✅ Coverage reports correctly reflect actual coverage per backend
⚠️ Patch coverage metric doesn’t reflect mutually exclusive code paths
✅ True coverage quality is validated by passing tests and protocol compliance
See Also
Testing - General testing guide
Database Backends Reference - Database backend comparison
PostgreSQL Migration Guide - PostgreSQL migration guide