Running WordPress PHPUnit Tests With Docker
Tags: wordpress, php, docker, testing
Published: 2017-04-11 04:31:57

---
title: Running WordPress PHPUnit Tests With Docker
published: true
description: Discussing setting up unit tests with WordPress and Docker, and highlighting an issue that I ran into.
cover_image: 
tags: wordpress, php, docker, testing
---

<img src="http://forest.stfhs.net/forest/wp-content/uploads/2017/04/docker-wordpress-phpunit-820x461.3.jpg">

I recently moved my web development workspace from MAMP to LAMP with Docker. The transition was difficult, due to issues with Ruby and RVM on my host machine. Now that it is working, all is well!

When I started tinkering with Docker, my goal was just to see if I could replicate my WordPress development environment. After I did that, I improved it a bit. Now, i've suitably compartmentalized each project. Each WordPress project has its own WordPress installation, MySQL server, error logs, plugin and theme directories.

The only thing missing was being able to run unit tests!

I vaguely remember having a frustrating time getting the Core WordPress tests to run with PHPUnit, the last time I set it up. This time was equally frustrating. I found an unfortunate lack of up-to-date and complete resources to deal with this process, so I made this article to fill the gap! I hope this helps someone avoid the same frustrations I experienced. If not, eh, at least I have the process documented for my future self.

The error that I kept receiving upon running `$ phpunit` was some HTML content, and a load of errors. The essence of it being, `<h1>Error establishing a database connection</h1>`.

Rather than including a testing database in each WordPress project, I created a MySQL container to be shared by all of my projects. I also configured the container to restart whenever the Docker daemon starts, so that it will always be available.

### Setting up WordPress Core Tests

In the same directory as my other WordPress projects (which contain individual `Dockerfile` and `docker-compose.yml` files), I created a `wordpress-develop` directory. To this new directory, I cloned the WordPress Core Tests repository.

```bash
$ svn co https://develop.svn.wordpress.org/trunk/ wordpress-develop
```

I then prepared the `wp-tests-config.php` file within `wordpress-develop/`. I found where the various global variables were being set at the bottom of the file, and updated them as follows:

```php
define( 'DB_NAME', 'wordpress' );
define( 'DB_USER', 'root' );
define( 'DB_PASSWORD', 'root' );
define( 'DB_HOST', '127.0.0.1:914' );

# ...

define( 'WP_TESTS_DOMAIN', 'localhost' );
define( 'WP_TESTS_TITLE', 'Testing' );
```

This sets the database name to wordpress, the username and password to root, and domain to localhost. The issue that I ran into earlier was that the database host didn't recognize the value `'localhost:914'` as valid. This resulted in failed attemps to connect to the database, when I ran `phpunit` from within `wordpress-develop/`. By exchanging `localhost` for a raw IP, `127.0.0.1` PHPUnit was able to connect. I actually found this fix recommended on a related <a href="http://wordpress.stackexchange.com/questions/203883/database-connection-problem-with-phpunit-and-wordpress" target="_blank" rel="nofollow">Stack Exchange</a> comment.

I chose the 914 port, because these <a href="https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers" target="_blank" rel="nofollow">UNIX port tables</a> indicate that the 914-986 range is officially unassigned. I needed a port that wouldn't get in the way, and 914 wasn't being used on my machine. I ran `$ curl http://127.0.0.1:914` just to check.

### Creating the MySQL daemon

Using a combination of `docker run` and the `restart` option, it is possible to create a MySQL container that will startup whenever the Docker daemon does. That includes when the host machine restarts.

```bash
$ docker run --name wptest-mysql --env MYSQL_ROOT_PASSWORD=root --env MYSQL_DATABASE=wordpress --env MYSQL_USER=root --env MYSQL_PASSWORD=root -p 0.0.0.0:914:3306 --restart=always -d mysql:5.7
```

The above command includes all of the data that we provided in the `wp-tests-config.php` file, and a bit more. The `name` option determines the name of the container; for easy identification I chose `wptest-mysql`, since `wordpress-develop-mysql` was a bit long. The `env` option is repeated several times, providing the container with the necessary environmental variables. The `p` option maps a port on the host machine to the container; so, `0.0.0.0:914` maps port `914` on the host to the port `3306` on the container. The `restart` option with the `always` value indicates that Docker should attempt to restart the container no matter how it exited. The `d` option indicates the image off of which to base the container. I used <a href="https://hub.docker.com/_/mysql/" target="_blank" rel="nofollow">MySQL version 5.7</a>.

At this point, running `$ docker ps -a` should reveal the new `wptest-mysql` container running with local port 914.

```bash
$ docker ps -a
24d9f30b5286        mysql:5.7           "docker-entrypoint..."   46 hours ago        Up 46 hours         0.0.0.0:914->3306/tcp   wptest-mysql
```

If it appears that the container is running properly, navigate to your `wordpress-develop` directory and run `$ phpunit`. If everything is running as it should, you'll see the WordPress test install begin to run, followed by the tests.

### Running WordPress tests elsewhere

Running the WordPress Core Tests is fantastic, but I really needed to run my own tests. In order to do this I took the path to my WordPress tests and assigned it to the `WP_TESTS_DIR` environmental variable in my `~/.bash_profile`. This environmental variable is relied on by the project-based `tests/bootstrap.php` files, which require the necessary WordPress files from the `wordpress-develop` directory.

Copy-pasted from my `~/.bash_profile`:

```bash
export DOCKER="$HOME/Documents/Programming/docker"
export WP_DEVELOP_DIR="$DOCKER/wordpress/wordpress-develop"
export WP_TESTS_DIR="$WP_DEVELOP_DIR/tests/phpunit"
```

If you have no need for the other environment variables, you can stick it all together like so (obviously, use the correct path on your machine):

```bash
export WP_TESTS_DIR="$HOME/Documents/Programming/docker/wordpress/wordpress-develop/tests/phpunit"
```

Run `$ . ~/.bash_profile` to activate the changes. After that, running `$ phpunit` next to a project's respective `phpunit.xml` file and `tests` directory should run the local tests, as expected.

That's it, woot!