Integrationstests für PHP mit Docker: Von A bis Z
\n\nModerne PHP-Entwicklung ist ohne qualitativ hochwertige Tests undenkbar. Während Unit-Tests isolierte Code-Stücke prüfen, stellt das Integrationstesting sicher, dass alle Komponenten des Systems zusammenarbeiten: Datenbank, Redis, externe APIs und das Dateisystem. Docker macht diesen Prozess reproduzierbar, schnell und unabhängig von der Entwicklungsumgebung. In diesem Artikel werden wir von Grund auf erklären, wie man Integrationstests für eine PHP-Anwendung mit Docker einrichtet.
\n\nWarum ist Docker das ideale Werkzeug für Integrationstests?
\n\nTraditionelle Probleme von Integrationstests:
\n- \n
- Umgebungsabhängigkeit – jeder Entwickler hat seine eigene Version von MySQL, PHP, Redis. \n
- Datenverschmutzung – Tests hinterlassen Müll in der echten Datenbank. \n
- Schwierigkeiten beim parallelen Ausführen – Tests geraten in Konflikt miteinander. \n
Docker löst diese Probleme:
\n- \n
- Jeder Test wird in einem sauberen Container mit bekannten Abhängigkeitsversionen ausgeführt. \n
- Container sind isoliert und werden nach dem Durchlauf entfernt. \n
- Docker Compose ermöglicht es, die gesamte Infrastruktur mit einem Befehl hochzufahren. \n
Schritt 1: Projektstruktur und Docker Compose
\n\nBeginnen wir mit einer typischen PHP-Anwendung auf Symfony. Erstellen wir eine Datei docker-compose.test.yml für die Testumgebung:
version: '3.8'\nservices:\n php:\n build:\n context: .\n dockerfile: Dockerfile.test\n environment:\n DATABASE_URL: "mysql://test:test@mysql:3306/test_db?serverVersion=8.0"\n REDIS_URL: "redis://redis:6379"\n depends_on:\n - mysql\n - redis\n\n mysql:\n image: mysql:8.0\n environment:\n MYSQL_ROOT_PASSWORD: root\n MYSQL_DATABASE: test_db\n MYSQL_USER: test\n MYSQL_PASSWORD: test\n tmpfs: /var/lib/mysql # Daten im Arbeitsspeicher – schneller\n\n redis:\n image: redis:7-alpine\n tmpfs: /data\n\nDie Datei Dockerfile.test:
FROM php:8.2-cli\n\nRUN docker-php-ext-install pdo_mysql\nRUN pecl install redis && docker-php-ext-enable redis\n\nCOPY --from=composer:latest /usr/bin/composer /usr/bin/composer\n\nWORKDIR /app\nCOPY . .\n\nRUN composer install --no-interaction --prefer-dist\n\nCMD ["vendor/bin/phpunit", "--configuration", "phpunit.xml.dist"]\n\nBeachten Sie tmpfs – dies mountet ein temporäres Dateisystem in den Arbeitsspeicher. Datenbank und Redis werden um ein Vielfaches schneller arbeiten als auf der Festplatte, was für schnelle Tests entscheidend ist.
Schritt 2: PHPUnit für Integrationstests konfigurieren
\n\nErstellen wir eine separate Konfiguration phpunit.integration.xml.dist:
<?xml version="1.0" encoding="UTF-8"?>\n<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"\n bootstrap="tests/bootstrap.php"\n colors="true">\n <testsuites>\n <testsuite name="Integration">\n <directory>tests/Integration</directory>\n </testsuite>\n </testsuites>\n <php>\n <env name="APP_ENV" value="test"/>\n <env name="KERNEL_CLASS" value="App\\Kernel"/>\n </php>\n</phpunit>\n\nDie Datei tests/bootstrap.php zur Initialisierung der Testumgebung:
<?php\n\nrequire dirname(__DIR__) . '/vendor/autoload.php';\n\n// Warten, bis MySQL und Redis bereit sind\n$maxAttempts = 30;\n$connected = false;\n\nfor ($i = 0; $i < $maxAttempts; $i++) {\n try {\n $pdo = new PDO(\n $_ENV['DATABASE_URL'],\n null, null,\n [PDO::ATTR_TIMEOUT => 1]\n );\n $connected = true;\n break;\n } catch (PDOException $e) {\n sleep(1);\n }\n}\n\