Integrationstests für PHP mit Docker: Von grundlegenden Szenarien zu industriellen Lösungen
\n\nIntegrationstests sind eine kritisch wichtige Phase der Entwicklung, die die Interaktion zwischen verschiedenen Systemkomponenten überprüft: Datenbank, Cache, externe APIs und die Geschäftslogik selbst. In der PHP-Welt, in der Anwendungen oft mit MySQL/PostgreSQL, Redis und Webservern zusammenarbeiten, wird Docker zu einem unverzichtbaren Werkzeug für die Erstellung isolierter, reproduzierbarer Testumgebungen. In diesem Artikel betrachten wir fortgeschrittene Techniken für Integrationstests von PHP-Anwendungen mit Docker, die Ihnen helfen, die Codequalität auf ein neues Niveau zu heben.
\n\nWarum Docker der ideale Begleiter für PHP-Integrationstests ist
\n\nTraditionelle Ansätze für Integrationstests leiden oft unter Umgebungsproblemen: Datenbanken können auf dem lokalen Rechner und dem CI-Server unterschiedlich sein, Ports sind belegt und Abhängigkeiten stimmen nicht überein. Docker löst diese Probleme radikal:
\n\n- \n
- Isolation: Jedes Testszenario wird in einem sauberen Container gestartet, wodurch Nebeneffekte vorheriger Tests ausgeschlossen werden. \n
- Reproduzierbarkeit: Images mit festen Versionen von PHP, Erweiterungen und Diensten stellen sicher, dass Tests auf jeder Maschine gleich ablaufen. \n
- Parallelität: Sie können mehrere Testsuiten gleichzeitig ausführen, jede in ihrem eigenen Container mit einer eindeutigen Datenbank. \n
- Geschwindigkeit: Moderne Tools wie Testcontainers oder Docker Compose ermöglichen es, Umgebungen in Sekundenschnelle hoch- und herunterzufahren. \n
Für PHP ist dies besonders relevant, da eine typische Anwendung mit vielen externen Ressourcen interagiert – von Warteschlangen (RabbitMQ) bis hin zu Suchmaschinen (Elasticsearch).
\n\nEinrichtung einer mehrschichtigen Testumgebung mit Docker Compose
\n\nDer erste Schritt zum fortgeschrittenen Testen ist die Erstellung einer flexiblen docker-compose.yml, die nicht nur PHP, sondern auch alle erforderlichen Dienste enthält. Betrachten wir ein Beispiel für eine Anwendung mit Laravel/Symfony, die MySQL, Redis und eine externe REST-API verwendet:
version: '3.8'\n\nservices:\n php-test:\n image: php:8.2-cli\n volumes:\n - ./:/app\n working_dir: /app\n environment:\n - DB_HOST=mysql-test\n - DB_DATABASE=test_db\n - REDIS_HOST=redis-test\n - API_BASE_URL=http://mock-api:8080\n depends_on:\n mysql-test:\n condition: service_healthy\n redis-test:\n condition: service_started\n mock-api:\n condition: service_started\n\n mysql-test:\n image: mysql:8.0\n environment:\n MYSQL_ROOT_PASSWORD: root\n MYSQL_DATABASE: test_db\n healthcheck:\n test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]\n interval: 5s\n timeout: 3s\n retries: 5\n\n redis-test:\n image: redis:7-alpine\n\n mock-api:\n image: wiremock/wiremock:latest\n volumes:\n - ./tests/mock-api:/home/wiremock\n\n\nDer entscheidende Punkt ist die Verwendung von WireMock zur Simulation externer APIs. Dies ermöglicht das Testen der Integration mit Diensten, die in der Testumgebung möglicherweise nicht verfügbar oder instabil sind. WireMock wird in einem separaten Container gestartet und gibt auf Basis von JSON-Konfigurationsdateien vordefinierte Antworten zurück.
\n\nVerwenden Sie zum Ausführen der Tests in dieser Umgebung das folgende Skript:
\n\n#!/bin/bash\ndocker-compose -f docker-compose.test.yml up -d\ndocker-compose -f docker-compose.test.yml exec php-test vendor/bin/phpunit --testsuite=Integration\ndocker-compose -f docker-compose.test.yml down\n\nFortgeschrittene Techniken: Dynamische Containererstellung und paralleler Start
\n\nWenn das Projekt wächst, kann eine statische docker-compose.yml zum Engpass werden. Hier kommt die Bibliothek Testcontainers ins Spiel (für PHP über das Paket testc