Pruebas de integración PHP con Docker: guía completa

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Pruebas de integración PHP con Docker: de la A a la Z

\n\n

El desarrollo moderno de PHP es impensable sin pruebas de calidad. Mientras que las pruebas unitarias verifican fragmentos de código aislados, las pruebas de integración aseguran que todos los componentes del sistema funcionen juntos: base de datos, Redis, API externas y el sistema de archivos. Docker hace que este proceso sea reproducible, rápido e independiente del entorno del desarrollador. En este artículo, analizaremos cómo configurar las pruebas de integración de una aplicación PHP con Docker desde cero.

\n\n

¿Por qué Docker es la herramienta ideal para pruebas de integración?

\n\n

Problemas tradicionales de las pruebas de integración:

\n
    \n
  • Dependencia del entorno — cada desarrollador tiene su propia versión de MySQL, PHP, Redis.
  • \n
  • Contaminación de datos — las pruebas dejan residuos en la BD real.
  • \n
  • Dificultad de ejecución paralela — las pruebas entran en conflicto entre sí.
  • \n
\n\n

Docker resuelve estos problemas:

\n
    \n
  • Cada prueba se ejecuta en un contenedor limpio con versiones conocidas de las dependencias.
  • \n
  • Los contenedores están aislados y se eliminan después de la ejecución.
  • \n
  • Docker Compose permite levantar toda la infraestructura con un solo comando.
  • \n
\n\n

Paso 1: Estructura del proyecto y Docker Compose

\n\n

Comencemos con una aplicación PHP típica en Symfony. Crearemos el archivo docker-compose.test.yml para el entorno de pruebas:

\n\n
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  # Datos en memoria — más rápido\n\n  redis:\n    image: redis:7-alpine\n    tmpfs: /data
\n\n

Archivo Dockerfile.test:

\n\n
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\n

Observe el tmpfs — es un montaje del sistema de archivos temporal en memoria. La base de datos y Redis funcionarán mucho más rápido que en disco, lo cual es crítico para pruebas rápidas.

\n\n

Paso 2: Configuración de PHPUnit para pruebas de integración

\n\n

Crearemos una configuración separada phpunit.integration.xml.dist:

\n\n
<?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\n

Archivo tests/bootstrap.php para inicializar el entorno de pruebas:

\n\n
<?php\n\nrequire dirname(__DIR__) . '/vendor/autoload.php';\n\n// Esperamos a que MySQL y Redis estén listos\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\                

Blogs

Book Recommendations