How to Test PHP Apps Running in Docker Containers

DevOps 
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.

Prerequisites

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

Option number one - docker compose run

At first, I thought that I’d use docker compose run.

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).

Option number two - docker compose exec

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 developers 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 these tutorials too...

How to Deploy a PHP App to Production With Docker Compose
Sun, Nov 12, 2023

How to Deploy a PHP App to Production With Docker Compose

Want to know how to deploy a PHP app to production (or any other remote environment)? In this tutorial, I’ll show you all the steps involved, and provide background information along the way, so you can build on what you’ll learn.

Override an Image's Command with Docker Compose
Thu, Oct 26, 2023

Override an Image's Command with Docker Compose

Sometimes, you need to override an image’s command when launching a container with Docker Compose. If you need to do that, in this tutorial I’m going to show you how — without the need to update an image’s Dockerfile or shell scripts.

Override an Image's Command with Docker Compose
Thu, Oct 26, 2023

Override an Image's Command with Docker Compose

Sometimes, you need to override an image’s command when launching a container with Docker Compose. If you need to do that, in this tutorial I’m going to show you how — without the need to update an image’s Dockerfile or shell scripts.


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