Integration Testing PHP with Docker: Advanced Level

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Integration Testing PHP with Docker: From Basic Scenarios to Industrial Solutions

\n\n

Integration testing is a critically important development stage that verifies the interaction between various system components: the database, cache, external APIs, and the business logic itself. In the PHP world, where applications often work in conjunction with MySQL/PostgreSQL, Redis, and web servers, Docker becomes an indispensable tool for creating isolated, reproducible test environments. In this article, we will explore advanced techniques for integration testing PHP applications using Docker that will help you take code quality to the next level.

\n\n

Why Docker is the Ideal Companion for PHP Integration Tests

\n\n

Traditional approaches to integration testing often suffer from environment issues: databases may differ on the local machine and CI server, ports may be occupied, and dependencies may not match. Docker solves these problems radically:

\n\n
    \n
  • Isolation: each test scenario runs in a clean container, eliminating side effects from previous tests.
  • \n
  • Reproducibility: images with fixed versions of PHP, extensions, and services guarantee that tests will run identically on any machine.
  • \n
  • Parallelism: you can run multiple test suites simultaneously, each in its own container with a unique database.
  • \n
  • Speed: modern tools such as Testcontainers or Docker Compose allow you to spin up and tear down environments in seconds.
  • \n
\n\n

This is especially relevant for PHP, as a typical application interacts with many external resources — from queues (RabbitMQ) to search engines (Elasticsearch).

\n\n

Setting Up a Multi-Level Test Environment with Docker Compose

\n\n

The first step towards advanced testing is creating a flexible docker-compose.yml that includes not only PHP but also all necessary services. Let's consider an example for a Laravel/Symfony application that uses MySQL, Redis, and an external REST API:

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

The key point is the use of WireMock to simulate external APIs. This allows you to test integration with services that may be unavailable or unstable in the test environment. WireMock runs in a separate container and returns predefined responses based on JSON configuration files.

\n\n

To run tests inside this environment, use the script:

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

Advanced Techniques: Dynamic Container Creation and Parallel Execution

\n\n

When a project grows, a static docker-compose.yml can become a bottleneck. This is where the Testcontainers library comes to the rescue (available for PHP via the testc

Blogs

Book Recommendations