Skip to main content

Docker4Drupal and Functional tests

Writing test is essential for creating a stable application, and writing Functional tests in Drupal 8 is the best way to get started with testing. There are 3 more test types in Drupal 8 (Kernel, Unit and Functional javascript tests), but if you are new to writing tests then it might the best if you start with the Functional tests first. To be able to run Functional tests if you are using Docker4Drupl you have to configure a few things first.

If you know how Behat works then you should know that Functional tests are very similar. You are writing a step by step instructions what the testing system should do for you -- essentially avoiding having a QA person go around your site and clicking buttons. And you can run these tests whenever you want and how many times you want. That means that you can always be sure that adding a new feature or refactoring an existing feature will not break your application or site. Also, tests are a good way to document how everything works, without actually having to write documentation.

To be able to run Functional tests if you are using Docker4Drupl you have to configure a few things first. To avoid permission issues you should use the latest and greatest version Docker4Drupal. As of writing this blog post that is version 5.4.1. Older versions have some permission issues that may prevent you from running tests, so if you don't want to deal with those just use the latest version.

Every Drupal 8 installation comes with the phpunit.xml.dist file. This is the default configuration file for PHPUnit and it's located in the core folder. Copy and rename this file to phpunit.xml

For PHPUnit to work with Docker4Drupal this is what you have to put inside this file:

<?xml version="1.0" encoding="UTF-8"?>

<phpunit bootstrap="tests/bootstrap.php" colors="true"
beStrictAboutTestsThatDoNotTestAnything="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutChangesToGlobalState="true">

   <php>
      <ini name="memory_limit" value="-1"/>
      <ini name="error_reporting" value="32767"/>
      <env name="SIMPLETEST_BASE_URL" value="http://nginx"/>
      <env name="SIMPLETEST_DB" value="mysql://drupal:drupal@mariadb/drupal"/>
      <env name="BROWSERTEST_OUTPUT_DIRECTORY" value="/var/www/html/web/sites/default/files/simpletest/browser_output"/>
   </php>

</phpunit>

As you can see we are setting the memory limit to unlimited and error reporting to all. Base URL of your site is not what you type in the browser's address bar. So, the value of SIMPLETEST_BASE_URL is not http://drupal.docker.localhost but http://nginx. For connecting to the database we are using default Docker4Drupal credentials drupal/drupal. If you changed those values inside your docker-compose.yml file then use your values. Having a properly configured database connection is very important, otherwise you won't be able to run tests.

Now, it's time to try running a test. Enter your PHP container like this

docker-compose exec php bash

and execute BigPipe Functional tests by using the following command:

vendor/bin/phpunit -c web/core web/core/modules/big_pipe/tests/src/Functional/BigPipeTest.php

And that's it. You can now successfully execute your Functional tests inside Docker. All you need now is to actually learn how to write tests and make sure that most of your code is covered by tests. To get started you can see a simple Functional test that I wrote for my Config Delete module. You can find it here: https://github.com/gnikolovski/config_delete/blob/8.x-1.x/tests/src/Functional/ConfigDeleteUITest.php
 

Update: I wrote a follow-up article on my personal blog that explains how to run Functional Javascript tests if you are using Docker4Drupal.