How to Test PHP Apps Running in Docker Containers

How to Test PHP Apps Running in Docker Containers

Docker and Docker Compose simplify setting up local development environments for developing PHP apps and for deploying them, whether locally or remotely. But, when your PHP app is running inside a Docker container, how do you run your tests — especially test suites that depend on resources such as database or caching servers? In this tutorial, I’ll show you how to do so.

At first glance, this might not seem like much of a problem. However, at least when I was first getting up to speed with Docker, I didn’t know how?

If I was using a Vagrant-based virtual machine, for example, then I’d run vagrant ssh to SSH into the virtual machine. Then I’d run the tests as I normally would, and see if any tests were red. Alternatively, I would execute the tests remotely in the virtual machine, instead of ssh’ing in first.

After a bit of searching, I found that it’s not that difficult. You just have to use the correct Docker or Docker Compose command.


To follow along with this tutorial, make sure you have the following:

Start the demo application

First, deploy the application locally by running the following command.

docker compose up -d

If you open http://localhost:8080 in your browser of choice, it should look similar to the following screenshot.

It doesn’t do a lot, just indulge my love of the 2010 - 2020 reboot of Hawai’i Five-O by showing a list of the main cast members over the course of the series.

If you’ve had a look at the Docker Compose configuration in compose.yml, you’d see that the application is quite simplistic. It has three containers (or services):

  • One for NGINX to handle requests (either serving up static files, or passing off requests to PHP and passing back its response)
  • One for PHP to handle dynamic requests
  • One for MariaDB, as the site’s content is stored there

This can be visualized in the illustration below.

Visualisation of a location development environment using Docker

What not to do

At first I thought that docker run was how you ran them. This will boot up a new instance of the PHP container, on a separate network, without any container which might be needed to perform the tests, such as one providing a database or cache server. Given that, it’s likely that the tests would fail.

Instead, you need to use docker exec. This command connects to an existing, running, container. So, it will be in the same network with the other containers which it would need. As a result it will be able to access them and execute the tests successfully (assuming they all should pass).

Run tests when using Docker Compose

If you look in the application’s source, you’ll see that the test suite is powered by PHPUnit. What’s more, you’ll see that composer.json defines the Composer script test to simplify running the PHPUnit test suite.

So, run the test suite, you only need to run the following command:

docker compose exec php php /usr/bin/composer test

It’s not that different from running tests in either a virtual machine, or locally.

Using exec Docker will execute the command php composer test in the container named php. It’s quite similar to running a command on a remote server with ssh or vagrant ssh using the -c or --command switches.

What about running an individual test, such as test/AppTest/Handler/HomePageHandlerTest.php, which has covering tests for src/App/src/Handler/HomePageHandler. To do this, you’d just add the path to the test class at the end of the previous command, as follows:

docker compose exec php composer test test/AppTest/Handler/HomePageHandlerTest.php

Running the tests directly inside the running container takes only a little more effort. You’d first SSH into the running (php) container, by running the following command.

docker compose exec php /bin/bash

In the command above, change /bin/bash to whatever shell is available in your container, such as ash or zsh. Then, you run your test suite, whether using one of the earlier approaches, or using a different tool or framework entirely. For example:

# Run the entire test suite
composer test

# Run just one test
composer test test/AppTest/Handler/HomePageHandlerTest.php

Run tests with a single Docker container

If you’d dockerised your PHP application inside a single Docker container, and had started it with docker run instead, the command is almost exactly the same. If that was the case, you’d use the command below, instead, after replacing the placeholder (<<Container's Name>>) with the image’s name.

docker exec <<Container's Name>> composer test

If you wanted to run the tests within the container, you’d first exec into it, using the command below.

docker exec --interactive --tty <<Container's Name>> /bin/bash

Then, you’d run the Composer test script as before.

And that’s how to run PHP tests when using Docker and Docker Compose

While there are many approaches to doing so, this one at least doesn’t make things overly complicated.

By making only a slight addition to your local Docker development environment, you are now able to run all your tests, regardless of their type, as easily as you would if you were using a Vagrant-based virtual machine, or one of the MAMP, WAMP, or LAMP stacks.

Do you need to get your head around Docker Compose quickly?
What about needing to dockerize existing applications to make them easier to deploy, reducing the time required for develwpers to get started on projects, or learning how to debug an existing Docker Compose-based app? Then this free book is for you!

You might also be interested in...

Want more tutorials like this?

If so, enter your email address in the field below and click subscribe.

You can unsubscribe at any time by clicking the link in the footer of the emails you'll receive. Here's my privacy policy, if you'd like to know more. I use Mailchimp to send emails. You can learn more about their privacy practices here.

Join the discussion

comments powered by Disqus