Overview
Integration tests verify that the MCP Server works correctly with real external services (PostgreSQL, OpenFGA, Redis, etc.). All integration tests run in isolated Docker containers, ensuring:- ✅ Zero manual setup - One command runs everything
- ✅ Complete isolation - No conflicts with local development
- ✅ 100% reproducible - Same environment everywhere (local, CI, team)
- ✅ Fast cleanup - All data deleted automatically
- ✅ Reliable - Tests always pass in CI/CD
Quick Start
Commands
Basic Usage
Advanced Usage
Architecture
Services
Integration tests use these containerized services:- postgres-test - PostgreSQL 16 (in-memory via tmpfs)
- openfga-test - OpenFGA with memory datastore
- redis-test - Redis (no persistence)
- test-runner - Python container running pytest
Network Isolation
All services run in an isolated Docker network (test-network):
- No port conflicts with local development
- Services communicate via service names (e.g.,
postgres-test:5432) - No ports exposed to host (unless debugging)
Environment Variables
The test runner automatically sets:TESTING=true- Enables integration test modeOPENFGA_API_URL=http://openfga-test:8080POSTGRES_HOST=postgres-testREDIS_HOST=redis-testENABLE_TRACING=false- Cleaner output
Writing Integration Tests
Test Markers
Mark integration tests with@pytest.mark.integration:
Using Real Services
Integration test fixtures connect to real services:Available Fixtures
Fromtests/conftest.py:
- integration_test_env - Returns True if running in Docker
- postgres_connection_real - Real PostgreSQL connection (asyncpg)
- redis_client_real - Real Redis client (redis.asyncio)
- openfga_client_real - Real OpenFGA client
- Skip if not in Docker environment
- Connect to test services
- Clean up after tests
Debugging
View Service Logs
Keep Containers Running
Run Single Test
CI/CD Integration
GitHub Actions
Integration tests run automatically in CI:- ✅ Removed
continue-on-error: true(tests are now reliable) - ✅ No manual service setup required
- ✅ Faster with Docker layer caching
Performance
Timing
| Phase | Duration |
|---|---|
| Build test image (first time) | ~60s |
| Build test image (cached) | ~5s |
| Start services | ~10s |
| Run tests | ~30s |
| Cleanup | ~2s |
| Total (first run) | ~100s |
| Total (cached) | ~50s |
Optimization Tips
- Use BuildKit caching (already enabled)
- Keep containers for re-runs during development
- Run unit tests first (fail fast)
- Test locally before pushing to CI
Troubleshooting
Tests Time Out
Services Won’t Start
Port Conflicts
Integration tests use isolated network with no exposed ports. If you see port conflicts:Permission Errors
Local Development Workflow
Recommended Flow
Alternative: Keep Services Running
Configuration
docker-compose.test.yml
Test services configuration:- In-memory databases (fast, ephemeral)
- Health checks (tests wait for ready)
- No volumes (clean state every run)
- Isolated network
Dockerfile.test
Test runner image:- Python 3.12
- Test dependencies only
- Environment pre-configured
- Fast builds with caching
Test Environment Variables
Set indocker-compose.test.yml:
TESTING=true- Enables test mode- Service URLs (postgres-test, redis-test, etc.)
- Disabled observability for cleaner output
Best Practices
- Use Docker for CI/CD: Always
make test-integrationin workflows - Keep tests fast: Use unit tests for logic, integration for service interaction
- Clean up properly: Use fixtures for setup/teardown
- Isolate tests: Don’t depend on test execution order
- Document requirements: Note which services each test needs
- Test one thing: Integration test should verify service interaction, not business logic
Related Documentation
- Testing Guide - Overview of all test types
- Docker Deployment - Docker best practices
- CI/CD Pipeline - GitHub Actions workflows
Last Updated: 2025-10-14 Version: 2.5.0 (Containerized integration tests)