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.
$ 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:
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 Stack Exchange comment.
I chose the 914 port, because these UNIX port tables 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.
$ 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 MySQL version 5.7.
At this point, running $ docker ps -a
should reveal the new wptest-mysql
container running with local port 914.
$ 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
:
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):
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!
Top comments (0)