Running Drupal's PHPUnit test suites on DDEV

DDEV is a local development stack built on top of Docker. It gives you all of your environment needs without messy configured on your host machine, without needing to know Docker or configure your own containers. Which is great, and makes life easier. Instead of just using DDEV to develop your site or application locally, why not also run your tests within it?

I have had quite a few people ask me how I configure my setup for testing with Drupal’s PHPUnit test suites. I usually link them to my blog post from two and half years ago: Commerce 2.x: Unit, Kernel, and Functional Tests Oh My!. It uses SQLite and PHP on the host machine. This is all and fine except:

  • You do not and cannot install SQLite and the SQLite extension for PHP on your host
  • You do not want or cannot install PHP on your host
  • Your local is setup to use the latest version of PHP, but the client project is still back a few versions.

All of these are the same reasons for using a virtual machine or containerized local development stack. So, it is fitting we run our tests within these local stacks as well! This is a threeish-part series. This is part one, where you’ll get up and running and able to execute your most common testing scenarios. Part two will consist of setting up to run Drupal’s FunctionalJavascript testing capabilities. And the third will be running Drupal’s new JavaScript testing framework, Nightwatch.js

First, make sure your DDEV project is up and running. You’ll be executing PHPUnit from within the web container and accessing the database container for Drupal’s Kernel, Functional, and FunctionalJavascript tests.

Thumbnail

Okay, next we need to configure PHPUnit. Drupal core ships with a distribution version of phpunit.xml named as phpunit.xml.dist. This configuration file tells Drupal various things: how test suites are defined, where tests can be discovered, and environment variables (like the database connection.) We need to copy that file and name it as phpunit.xml. Go into Drupal’s core folder and rename the file. 

Thumbnail

We care about modifying two environment variables

  • SIMPLETEST_BASE_URL, this defaults to http://localhost and is used as the URL for the browser emulators in Functional and FunctionalJavascript tests
  • SIMPLETEST_DB, this is the database connection string and is required to run any of Drupal’s test suites beyond unit

Edit the entry for SIMPLETEST_BASE_URL and set it to http://localhost. For SIMPLETEST_DB we need to pass a connection string formatted as mysql://username:[email protected]/databasename. This requires the database connection information for our database provided by DDEV. Luckily, there is the handy ddev describe command that will give us this information.

Open a terminal and, from your DDEV project, execute ddev describe to receive connection info about your DDEV project.

Thumbnail

As you can see under MySQL Credentials, everything we need is just db. This is the out of the box setup, and unless you changed something (or DDEV changed, it’s safe to guarantee it probably is for you as well. So, our database connection string is going to look like: mysql://db:[email protected]/db.

Thumbnail

Now, to run the tests. Let’s SSH into the web container using ddev ssh. To test and make sure things work, let’s run all of the tests for the Action module, which contains Unit, Kernel, and Functional tests.

Open a terminal and run ddev ssh from your DDEV project. This will bring you to /var/www/html/web in your web container, the docroot of your Drupal site. From here we can execute our PHPUnit command:

ddev ssh
../vendor/bin/phpunit -c core core/modules/action

Here’s an example of the output you should see. I added the debug flag to show that specific test classes were being executed.

Thumbnail

Yay! We’re executing Unit, Kernel, and Functional tests. Until… we attempt to run a FunctionalJavascript test. To run FunctionalJavascript tests we require a browser emulator that can execute JavaScript. If the browser emulator is not running, all of the tests will be skipped 😞 Read the next post Running Drupal's FunctionalJavascript tests on DDEV to get up and running with Drupal's FunctionalJavascript testing..

Thumbnail