Drupal Testing Container
A Docker container and
template for testing individual Drupal modules with:
- Unit and Kernel tests
- Behat tests
- Code standards
- Code coverage
If you want to test a whole Drupal site, and not an individual module, see
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
- Getting started with CircleCI
- Getting started with tests
- Overriding PHPUnit configuration
- Applying patches
- Updating templates in modules
- Testing against a new version of Drupal
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
- A Dockerfile extending the
official Drupal image to support
Composer, Robo, and code coverage reports.
- Templates for jobs running with CircleCI.
- Most of the logic is in shell scripts and Robo commands, making it easy to
run under a different CI tool.
this example repository using Drupal's node module
for a live example of how this template is set up, and what sort of reports you
will see in CircleCI for each job. The
module is another good example using this template.
Getting started with CircleCI
cdto the directory with your Drupal module. Make sure it's a git
bash -c "$(curl -fsSL https://github.com/deviantintegral/drupal_tests/raw/master/setup.sh)"
- Review and commit the new files.
- Connect the repository to CircleCI.
- Add a
COMPOSER_AUTHenvironment variable to Circle if you are using
private repositories. See the composer documentation on
for more details.
- Push a branch . At this point, all jobs should run, though no tests are
actually being executed.
- To override a given hook, copy it to your
.circlecidirectory. Then, in
the run step, copy the script to the root of the project. For example, if
you need to override
runstep for the
code_sniffersection would become:
- run: working_directory: /var/www/html command: | cp ./modules/$CIRCLE_PROJECT_REPONAME/.circleci/code-sniffer.sh /var/www/html ./code-sniffer.sh $CIRCLE_PROJECT_REPONAME
Getting started with tests
If you ran
setup.sh these steps have been done automatically.
- Copy all of the files and directories from
templates/moduleto the root of
your new module.
phpunit.core.xml.distand set the whitelist paths for coverage
my_modulewith your module name.
MyModulewith your module name.
- In your module's directory, include the required development dependencies:
$ composer require --dev --no-update \ behat/mink-selenium2-driver \ drupal/coder \ drupal/drupal-extension \ bex/behat-screenshot \ phpmd/phpmd \ phpmetrics/phpmetrics
- Start writing tests!
directory structure as with Drupal contributed modules. If the Drupal testbot
could run your tests, this container should too.
Tests are executed using
run-tests.sh. Make sure each test class has a proper
@group annotation, and that base classes do not have one. Likewise, make sure
that each test is in the proper namespace. If a Unit test is in the Kernel
namespace, things will break in hard-to-debug ways.
types of tests.
Behat tests do not run on drupal.org, but we store them in a similar manner.
Most Behat implementations are testing sites, and not modules, so their docs
suggesting tests go in
sites/default/behat don't apply. Instead, place tests
tests/src/Behat, so that you end up with:
Behat can be buggy when using relative paths. To run your scenarios locally,
run from the Drupal root directory with an absolute path to your configuration.
$ vendor/bin/behat -v -c $(pwd)/modules/my_module/tests/src/Behat/behat.yml
Debugging Behat tests
Behat is configured to use Selenium and Chrome along with a VNC server. If your
CI provider allows SSH access to containers, you can forward ports to inspect
In CircleCI, first rebuild the Behat job with SSH. Once you have the SSH command
to run, forward ports as needed. For example, to point port
8080 on your local
machine to Apache, and port
5900 to the VNC server, run:
$ <ssh command copied from the job> -L8080:localhost:80 -L5900:localhost:80
The container's site will now be available at
http://localhost:8080. To log
in to Drupal, use
drush user-login from SSH inside of the container.
$ cd /var/www/html $ vendor/bin/drush -l localhost:8080 user-login
Click the link that is printed out and you should be logged in as
For VNC, connect to
localhost:5900 with the VNC client of your choice. The
VNC password is
secret. If you manually run Behat tests from within the
SSH connection, you should see Chrome start and tests execute.
Overriding PHPUnit configuration
phpunit.core.xml.dist configuration file is copied to Drupal's
directory before running tests. Feel free to edit this file in each module as
Sometimes, a module needs to apply patches to Drupal or another dependency to
work correctly. For example, out of the box we patch Coder to not throw errors
on Markdown files. To add or remove additional patches, edit
using the same format as
Updating templates in modules
To update to the latest release of this template, simply run
Be sure to review for any customizations you may want to preserve. For example:
$ git checkout -b update-circleci $ bash -c "$(curl -fsSL https://github.com/deviantintegral/drupal_tests/raw/master/setup.sh)" $ git add -p # Add all changes you want to make. $ git checkout -p # Remove any changes you don't want to make. $ git status # Check for any newly added files. $ git commit
In terms of semantic versioning, we consider the Docker image to be our
"public" API. In other words, we will bump the major version (or minor pre-1.0)
if updating the container also requires changes to the template files in a
Testing against a new version of Drupal
The Docker container builds against the stable branch of Drupal core, such as
8.3.x and not a specific release like 8.3.2. This helps ensure tests always run
with the latest security patches. If you need to reproduce a build, see your
build logs for the specific image that was used:
Status: Downloaded newer image for andrewberry/drupal_tests:0.0.3 using image andrewberry/drupal_tests@sha256:f65f0915e72922ac8db1545a76f6821e3c3ab54256709a2e263069cf8fb0d4e2
When a new minor version of Drupal is released:
- Update the
Dockerfileto point to a new release, such as
- Build the container locally with
docker build -t drupal-8.4-test ..
- In a module locally, update
- Test locally with
circleci build --job run-unit-kernel-testsand so on for
- Submit a pull request to this repository.
- Add a
in Docker Hub with the new tag to ensure linked repositories cause a
- After merging and when Docker hub has built a new tag, update your
config.ymlto point to it.