Quick Start
Run the full test suite with linting:- Linting - Ruff code quality checks and formatting validation
- Type checking - mypy static type analysis
- Unit tests - pytest with parallel execution
Test Framework
GOV.UK Notify API uses:- pytest - Test framework
- pytest-xdist - Parallel test execution
- pytest-mock - Mocking utilities
- pytest-env - Environment variable management
- pytest-testmon - Test monitoring for faster re-runs
- moto - AWS service mocking
- freezegun - Time/date mocking
- requests-mock - HTTP request mocking
Running Tests
Full Test Suite
ruff check .- Lintingruff format --check .- Format checkingmypy- Type checkingpytest -n logical --maxfail=10- Tests with parallel execution
Unit Tests Only
Parallel Execution
Tests run in parallel using pytest-xdist with thelogical mode:
-n logical- Groups tests by module for better database handling--maxfail=10- Stops after 10 failures to save time
Watch Mode
Automatically re-run tests when files change:ptw(pytest-watch) - File watcherpytest-testmon- Smart test selection (only affected tests)
Specific Tests
Test Configuration
Test configuration is defined inpytest.ini:
Environment Variables
Tests automatically set:NOTIFY_ENVIRONMENT=testREDIS_ENABLED=0(Redis disabled by default in tests)- Test API keys for SMS providers
Test Options
-p no:warnings- Suppresses warningsxfail_strict = true- Marks unexpectedly passing xfail tests as failures
Test Databases
Pytest-xdist creates separate databases for parallel test execution.Database Naming
When running with-n logical, pytest creates:
test_notification_api_master- Master databasetest_notification_api_gw0,gw1,gw2, etc. - Worker databases
Clean Up Test Databases
Linting
Run linting and formatting checks:Ruff
mypy
Code Quality Tools
Pre-commit Hooks
Pre-commit hooks automatically run on every commit:Type Hints
The project uses mypy for static type checking. Type stubs are included for:types-cachetoolstypes-pycurltypes-python-dateutiltypes-requests
Testing Utilities
AWS Service Mocking
Usemoto to mock AWS services:
Time/Date Mocking
Usefreezegun for time-based tests:
HTTP Request Mocking
Userequests-mock for HTTP requests:
Flaky Test Handling
Use theflaky decorator for tests that occasionally fail:
Docker Testing
The repository includes Docker images for testing:Test Image
Concourse Test Image
Theconcourse_tests target includes PostgreSQL 15 for CI/CD:
Writing Tests
Test Location
Tests should mirror the application structure:Test Naming
- Test files:
test_*.pyor*_test.py - Test functions:
test_* - Test classes:
Test*
Best Practices
- Isolate tests - Each test should be independent
- Use fixtures - Leverage pytest fixtures for setup/teardown
- Mock external services - Don’t make real API calls
- Clear assertions - Use descriptive assertion messages
- Test edge cases - Don’t just test the happy path
Continuous Integration
Tests run automatically in Concourse CI/CD pipeline:- Uses the
concourse_testsDocker image - PostgreSQL 15 runs in the container
- All test databases are created/destroyed automatically
Performance
Test Execution Time
To identify slow tests:Database Performance
Tests use thelogical grouping strategy to minimize database conflicts and improve parallel execution performance.
Troubleshooting
Tests Hanging
If tests hang, check for:- Database connection issues
- Leftover test databases