Tests d'intégration PHP avec Docker : techniques avancées

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Tests d'intégration PHP avec Docker : niveau avancé

Les tests d'intégration sont une étape critique du développement, en particulier pour les applications PHP complexes interagissant avec des bases de données, des files d'attente, des API externes et d'autres services. Docker permet de créer un environnement isolé, aussi proche que possible de la production, et d'exécuter les tests dans des conditions reproductibles. Dans cet article, nous aborderons des techniques avancées : l'organisation des conteneurs de test, la simulation des dépendances externes, l'exécution parallèle et l'intégration avec CI/CD.



1. Architecture de l'environnement de test avec docker-compose

Pour les tests d'intégration, nous utilisons un fichier docker-compose.test.yml séparé, qui démarre uniquement les services nécessaires : PHP-FPM avec le code de test, une base de données (par exemple, PostgreSQL), Redis et, optionnellement, un serveur mock pour les API externes.

version: '3.8'services:  php-test:    build:      context: .      dockerfile: Dockerfile.test    volumes:      - .:/var/www/html    environment:      DATABASE_URL: "pgsql://test:test@db-test:5432/testdb"      REDIS_URL: "redis://redis-test:6379"      EXTERNAL_API_URL: "http://mock-server:1080"    depends_on:      - db-test      - redis-test      - mock-server

db-test: image: postgres:15-alpine environment: POSTGRES_DB: testdb POSTGRES_USER: test POSTGRES_PASSWORD: test ports: - "5433:5432" # Évite les conflits avec la base de données principale

redis-test: image: redis:7-alpine ports: - "6380:6379"

mock-server: image: mockserver/mockserver:latest environment: MOCKSERVER_PROPERTY_FILE: /config/mockserver.properties volumes: - ./tests/mockserver:/config ports: - "1080:1080"

Remarque : nous utilisons des ports séparés pour les services de test afin qu'ils n'interfèrent pas avec le développement local.



2. Préparation de PHPUnit et initialisation de la base de données de test

Configuration du fichier phpunit.xml pour les tests d'intégration :

<phpunit bootstrap="tests/bootstrap.php">    <testsuites>        <testsuite name="Integration">            <directory>tests/Integration</directory>        </testsuite>    </testsuites>    <php>        <env name="APP_ENV" value="test"/>        <env name="KERNEL_CLASS" value="App\\Kernel"/>    </php></phpunit>

Le fichier tests/bootstrap.php est responsable de l'initialisation du schéma de la base de données et du chargement des données de test :

require __DIR__ . '/../vendor/autoload.php';

// Création du schéma de la base de données$pdo = new PDO('pgsql:host=db-test;port=5432;dbname=testdb', 'test', 'test');$pdo->exec(file_get_contents(__DIR__ . '/../migrations/schema.sql'));

// Chargement des fixturesrequire __DIR__ . '/Fixtures/LoadFixtures.php';

Cette approche garantit que chaque exécution de test commence dans un état propre et prévisible.



3. Test avec des API externes : MockServer et WireMock

Pour simuler des services HTTP externes, nous utilisons MockServer (ou WireMock). Créons une configuration d'attentes dans un fichier JSON :

// tests/mockserver/expectations/payment.json{  "httpRequest": {    "method": "POST",    "path": "/api/v1/charge"  },  "httpResponse": {    "statusCode": 200,    "body": "{\\"status\\": \\"success\\", \\"transaction_id\\": \\"txn_123\\"}",    "headers": {      "Content-Type": "application/json"    }  }}

Dans le code PHP du test, nous envoyons une requête à l'URL réelle, qui pointe vers le mock-server via une variable d'environnement :

class PaymentIntegrationTest extends TestCase{    private PaymentService $paymentService;

protected function setUp(): void { $this->paymentService = new PaymentService( new HttpClient(['base_uri' => $_ENV['EXTERNAL_API_URL']])

Blogs

Book Recommendations