Introduction : pourquoi les tests d'intégration PHP dans Docker sont un must-have
Le développement d'applications PHP modernes se limite rarement à un seul serveur. Bases de données, caches (Redis, Memcached), files d'attente (RabbitMQ), API externes — tout cela nécessite de vérifier l'interaction des composants. Les tests unitaires isolent le code, mais ne garantissent pas que la classe A fonctionne correctement avec la classe B via une base de données réelle. C'est là que les tests d'intégration entrent en jeu.
Le problème de l'approche classique est la configuration de l'environnement. Le développeur passe des heures à configurer MySQL, à gérer les droits, à installer les extensions PHP. Docker résout ce problème une fois pour toutes. Dans cet article, nous allons voir comment organiser les tests d'intégration d'une application PHP en utilisant Docker et Docker Compose. Vous obtiendrez des configurations prêtes à l'emploi, des exemples de code et des recommandations d'optimisation.
1. Configuration de l'environnement Docker pour les tests PHP
1.1. Structure de base du projet
Supposons que nous ayons une application PHP simple sur Symfony ou Laravel (n'importe quel framework convient). Créons un fichier docker-compose.yml à la racine du projet :
version: '3.8'
services: php: build: . volumes: - .:/var/www/html environment: - DATABASE_URL=mysql://test_user:test_pass@db:3306/test_db depends_on: - db
db: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: root_pass MYSQL_DATABASE: test_db MYSQL_USER: test_user MYSQL_PASSWORD: test_pass ports: - "3307:3306" # Redirection vers un port non standard pour éviter les conflits avec la base de données locale
test_runner: image: php:8.2-cli volumes: - .:/var/www/html working_dir: /var/www/html entrypoint: ["vendor/bin/phpunit"] depends_on: - db - phpPoints clés :
- Le service
test_runnerutilise un conteneur séparé avec PHP CLI — cela isole l'exécution des tests de l'application principale. - La base de données est lancée avec un schéma vierge. Pour chaque exécution de tests, nous pouvons la recréer.
- Le port MySQL est redirigé vers
3307pour ne pas interférer avec la base de données locale du développeur.
1.2. Dockerfile pour l'application PHP
Créons un Dockerfile pour le service principal php :
FROM php:8.2-fpm
RUN docker-php-ext-install pdo_mysql mysqli
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
WORKDIR /var/www/html
COPY . .
RUN composer install --no-interaction --prefer-distCette image sera utilisée à la fois pour le développement et pour les tests. Il est important d'installer l'extension pdo_mysql — sans elle, les tests qui interagissent avec la base de données échoueront.
2. Rédaction de tests d'intégration avec PHPUnit
2.1. Configuration de base de PHPUnit
Assurez-vous d'avoir PHPUnit installé (via Composer). Le fichier phpunit.xml doit pointer vers la base de données de test :
<?xml version="1.0" encoding="UTF-8"?><phpunit bootstrap="vendor/autoload.php"> <php> <env name="DATABASE_URL" value="mysql://test_user:test_pass@db:3306/test_db" /> <env name="APP_ENV" value="test" /> </php> <testsuites> <testsuite name="Integration"> <directory>tests/Integration</directory> </testsuite> </testsuites></phpunit>2.2. Exemple de test d'intégration : interaction avec la base de données
Supposons que nous ayons un repository d'utilisateurs. Écrivons un test qui vérifie la sauvegarde et la recherche :
<?php
namespace App\\Tests\\Integration;
use App\\Entity\\User;use App\\Repository\\UserRepository;use Doctrine\\ORM\\EntityManagerInterface;use Symfony\\Bundle\\FrameworkBundle\\Test\\KernelTestCase;
class UserRepos