In this chapter, we will get introduced to Drupal 8 and cover the following recipes:
- Installing Drupal
- Using a distribution with Drupal
- Installing modules and themes
- Using multisites in Drupal 8
- Tools for setting up an environment
- Running tests: Simpletest and PHPUnit
This chapter will kick off with an introduction to installing a Drupal 8 site. We will walk through Drupal's interactive installer. We will cover installing Drupal using a command-line tool called Drush. Drupal provides two installation types: standard and minimal. Throughout this book, we will use the standard installation.
Once we have installed our Drupal 8 site, we will cover the basics of extending Drupal. We will discuss using distributions and installing contributed projects, such as modules and themes. We will also include uninstalling modules, as the process for uninstalling modules has changed in Drupal 8.
This book will involve a hands-on example for working with Drupal 8, and this chapter will provide information on setting up a local development environment. This chapter will also provide recipes on how to set up a Multisite installation in Drupal 8 and run the available test suites.
Before we get started, you should install Composer. Composer is the de facto package management tool for PHP. In case you are unfamiliar with Composer, it is just like using Gems for Ruby, npm for Node.js, and Bower for frontend libraries. Go to the Composer documentation to learn how to install Composer globally on your system:
There are many different methods to download Drupal and install it. In this recipe, we will focus on downloading Drupal from https://www.drupal.org/ and setting it up on a basic Linux, Apache, MySQL, or PHP (LAMP) server.
In this recipe, we will set up the files for Drupal 8 and step through the installation process.
Before we start, you will need a development environment that meets the new system requirements for Drupal 8:
- Apache 2.0 (or higher) or Nginx 1.1 (or higher) web server
- PHP 5.5.9 or higher, but PHP 5.6 or PHP 7 is recommended, as PHP 5.5 has reached its end-of-life support
- MySQL 5.5 or MariaDB 5.5.20 for your database
Note
You will need a user with privileges to create databases or a created database with a user who has privileges to make tables in that database.
- Access to upload or move files to the server
- While a default installation of PHP will work with Drupal, it does require certain PHP extensions, such as mbstring. Check out https://www.drupal.org/requirements/php for up-to-date requirement information.
Note
Drupal 8 ships with Symfony (https://symfony.com/) components. One of the new dependencies in Drupal 8, to support the Symfony routing system, is the Drupal Clean URL
functionality. If the server is using Apache, ensure that mod_rewrite
is enabled. If the server is using Nginx, the ngx_http_rewrite_module
must be enabled.
We will download Drupal 8 and place its files in your web server's document root. This is the /var/www
folder. If you used a tool, such as XAMPP, WAMP, or MAPP, consult the proper documentation to know your document root.
For full system requirements for Drupal 8, check out https://www.drupal.org/docs/8/system-requirements/. The Drupal.org documentation is currently being migrated. Also, review the Drupal 7 requirements page on https://www.drupal.org/docs/7/system-requirements/overview, which highlights Drupal 8 items, as well.
We need to follow these steps to install Drupal 8:
- First, we will need to navigate to https://www.drupal.org/download and download the latest release of Drupal 8.x. You can find the most recent and recommended release on the https://www.drupal.org/project/drupal page for Drupal 8 (8.3.1, 8.4.0, and so on). Extract the archive and place the files in your document root as the
drupal8
folder :

- Open your browser and visit your web server, for example,
http://localhost/drupal8
, which will then take you to the Drupal installation wizard. You will land on the new multilingual options install screen. Select your language and click onSave and continue
:

- On the next screen, select the default
Standard
option for the installation profile. This will provide us with a standard configuration with the most commonly used modules installed. - The next step will verify your system requirements. If your system does not have any reportable issues, the screen will be skipped. If you do have any requirement conflicts, you can resolve them and click on the button to try again.
Note
If you have requirement issues, the installer will report the specific issues. Nearly every requirement will link to a Drupal.org handbook page with solution steps.
- Enter the database information for Drupal. In most cases, you will only need to supply the username, password, and database name and leave others as defaults. If your database does not exist, the installer will attempt to create the database:

- Your Drupal 8 site will begin installing. When it is done installing the base modules, you will be taken to a site configuration screen.
- The configure site form provides the base configuration for your Drupal site. Enter your site name and the email address for the site. The site email will be used to send administrative notifications and has the originating email for outgoing emails from the Drupal site. This form allows you to set regional information regarding the country and time zone of the site. Setting the timezone ensures that time values display correctly.
- Fill in the site maintenance account information, also known as user 1, which acts in a similar way to the root on Unix-based systems. The site maintenance account is crucial. As stated, this acts as the first user and is given the user ID of 1. In Drupal, the user with the user ID of 1 often can bypass permission checks automatically and have global access.
- Enter the site's regional information, and check whether the site should check for updates available for modules enabled and Drupal itself. By checking for updates automatically, your site will report anonymous usage statistics to Drupal along with providing a summary of your version status. You have the option to also opt-in for the site to email you notifications of new releases, including security releases.
- When the information is satisfied, click on
Save and continue
, and congratulations, you installed Drupal! The next screen will provide you a link to your installed Drupal site.
The Drupal installation process will provide a Drupal installation for the selected language and install modules and configuration based on the installation profile (standard or minimal in this recipe.)
When you visit the installer, it reads the language code from the browser. With this language code, it will then select a supported language. If you choose a non-English installation, the translation files will be automatically downloaded from https://localize.drupal.org/. Previous versions of Drupal did not support automated multilingual installs. More on multilingual will be covered in Chapter 8, Multilingual and Internationalization.
The installation profile instructs Drupal what modules to install by default. Contributed install profiles are termed distributions; we will discuss this more in the next recipe.
When verifying requirements, Drupal checks application versions and PHP configurations. For example, if your server has the PHP Xdebug (https://xdebug.org) extension installed, the minimummax_nesting_level
must be 256 or else Drupal will not be installed (https://www.drupal.org/node/2393531).
The Drupal installation process is straightforward, but there are a few things worth discussing.
As mentioned earlier, to install Drupal, you will need to have access to a database server (or the ability to create one) and an existing database (or the ability to create one). This process will depend on your environment setup.
If you are working with a hosting provider, there is more than likely a web-based control panel. This should allow you to create databases and users. Refer to your hosting provider's documentation for more information on this topic.
If you are using phpMyAdmin (https://www.phpmyadmin.net/) on your server, often installed by MAMP, WAMP, and XAMPP, and have root access, you can create your databases and users by following these steps:
- Sign in to phpMyAdmin as the root user.
- Click on
Add a new User
from the bottom of the privileges page. - Fill in the user's information.
- Select to create a database for the user with all privileges granted.
- You can now use that user's information to connect Drupal to your database.
If you do not have a user interface but have a command-line access, you can set up your database and user using the MySQL command line. These instructions can be found in the core/INSTALL.mysql.txt
file. From the command line of your site, perform the following:
- Log in to MySQL:
$ mysql -u username -p
- Create the database; you will use the following command to create the
my_database
database:
$ CREATE DATABASE my_database CHARACTER SET utf8 COLLATE utf8_general_ci;
- Create a new user to access the database:
$ CREATE USER username@localhost IDENTIFIED BY 'password';
- Grant the new user permissions on the database, as follows:
$ GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES ON databasename.* TO 'username'@'localhost' IDENTIFIED BY 'password';
Drupal, like other content management systems, allows you to prefix its database tables from the database set-up form. This prefix will be placed before table names to help make them unique. Although it is not recommended, this would allow multiple installations to share one database. Utilizing table prefixes can, however, provide some level of security through obscurity since the tables will not be their default names:

You may also install Drupal using the PHP command-line tool, Drush. Drush is a command-line tool created by the Drupal community and must be installed if you wish to use it. Drush is covered in Chapter 13, The Drupal CLI.
Note
As of Drush 9, which supports Drupal 8.3+, this section is deprecated. Using Drush to download Drupal core or contributed modules will throw a warning to use Composer instead.
The pm-download
command will download packages from Drupal.org. The site-install
command will allow you to specify an installation profile and other options to install a Drupal site. The installation steps in this recipe could be run through Drush, as follows:
$ cd /path/to/web$ drush pm-download drupal-8 drupal8$ cd drupal8$ drush site-install standard -locale=en-US --account-name=admin --account-pass=admin -account-email=demo@example.com -db-url=mysql://user:pass@localhost/database
We used Drush to download the latest Drupal 8 and place it in a folder named drupal8
. Then, the site-install
command instructs Drush to use the standard install profile, configure the maintenance account, and provide a database URI string so that Drupal can connect to its database.
You can download Drupal using Composer, the de facto PHP package manager. The preferred method is to use the Drupal Composer project template provided by the community.
To build your Drupal 8 site, run the following commands:
$ cd /path/to/document/root$ composer create-project drupal-composer/drupal-project drupal8 --stability dev
Wait for the commands to finish--it may take some time, as it downloads all the required dependencies. You can feel free to grab a coffee (the first time takes a while; it primes caches. Have faith, it will be much faster the next time.)
When finished, you will find a different directory structure inside your drupal8
directory. The vendor
directory contains all third-party PHP libraries, and the web
directory contains your Drupal 8 site. You will need to modify your web server to use the web
directory as the new docroot within your drupal8
directory.
The project and its details can be found at https://github.com/drupal-composer/drupal-project, along with its full documentation.
If you choose to disable the update options, you will have to check manually for module upgrades. While most upgrades are for bug fixes or features, some are for security updates. It is highly recommended that you subscribe to the Drupal security team's updates. These updates are available on Twitter at @drupalsecurity
(https://twitter.com/drupalsecurity) or the feeds onhttps://www.drupal.org/security.
- For more on multilingual, check out Chapter 8, Multilingual and Internationalization
- For more on using the command line and Drupal, check out Chapter 13, The Drupal CLI
- Check out the Drupal.org handbook on installing Drupal at https://www.drupal.org/documentation/install
- Check out the Drupal.org handbook that discusses Drupal 8 and Composer at https://www.drupal.org/docs/develop/using-composer/using-composer-with-drupal
- Check out more information on Drush site install at https://drushcommands.com/drush-8x/core/site-install/
Why would you want to use a distribution? A distribution is a contributed installation profile that is not provided by Drupal core. Distributions provide a specialized version of Drupal with specific installed modules and themes along with specific configurations (content types, and blocks.) On Drupal.org, when you download an installation profile, it not only includes the profile and its modules but a version of Drupal core, hence the name distribution. You can find a list of all Drupal distributions at https://www.drupal.org/project/project_distribution.
We will follow these steps to download a distribution to use as a customized version of Drupal 8:
- Download a distribution from Drupal.org. For this recipe, let's use the Demo Framework provided by Acquia at https://www.drupal.org/project/df.
- Select the recommended version for the 8.x branch.
- Extract the folder contents to your web server's document root--you'll note that there is Drupal core; within the
profiles
folder, there's the installation profile's folder--df
. - Due to current Drupal.org packaging limitations, there is a manual step that you will need to run in order to install additional dependencies. Run the following command using your terminal inside of the extracted contents:
$ composer require "commerceguys/intl: ~0.7" "commerceguys/addressing: ~1.0" "commerceguys/zone: ~1.0" "embed/embed: ~2.2
- Install Drupal as you would normally, by navigating to your Drupal site in your browser.
- Follow the installation instructions in the site to install the distribution.
Installation profiles work by including additional modules that are part of the contributed project realm or custom modules. The profile will then define them as dependencies to be installed with Drupal. When you select an installation profile, you are instructing Drupal to install a set of modules on installation.
Demo Framework declares itself as an exclusive installation profile. Distributions that declare this are automatically selected and assumed to be the default installation option. The exclusive flag was added with Drupal 7.22 to improve the experience of using a Drupal distribution (http://drupal.org/node/1961012).
Distributions provide a specialized version of Drupal with specific feature sets, but there are a few items worth discussing.
The current standard for generating a built distribution is the utilization of Drush and makefiles. Makefiles allow a user to define a specific version of Drupal core and other projects (such as themes, modules, and third-party libraries) that will make up a Drupal code base. It is not a dependency management workflow, like Composer, but is a build tool.
If you take a look at the Demo Framework's profile
folder, you will see drupal-org.make
and drupal-org-core.make
. These are parsed by the Drupal.org packager to compile the code base and package it as a .zip
or .tar.gz
, like the one you downloaded.
As discussed in the first recipe's There's more... section, you can install a Drupal site through the Drush command-line tool. You can instruct Drush to use a specific installation profile by providing it as the first argument.
Note
As of Drush 9, which supports Drupal 8.3+, this section is deprecated. Using Drush to download Drupal core or contributed modules will throw a warning to use Composer instead.
The following command would install the Drupal 8 site using the Demo Framework:
$ cd /path/to/drupal8 $ drush pm-download df$ drush site-install df -db-url=mysql://user:pass@localhost/database
Currently, Drupal.org does not package distributions using Composer, which is why there was an extra step to add dependencies when installing the distribution. Many distributions provide project templates to make scaffolding projects simpler.
For example, the following command will set up a Demo Framework site with docroot
as the directory for the web server document root, which contains Drupal 8:
$ composer create-project acquia/df-project df
The project template is available on Acqua's GitHub at https://github.com/acquia/df-project/.
Another distribution, Open Social, provides a template of its own:
$ composer create-project goalgorilla/social_template
The project template is available at https://github.com/goalgorilla/social_template.
- Refer to Chapter 13, The Drupal CLI, for information on makefiles.
- Refer to Distribution documentation on Drupal athttps://www.drupal.org/documentation/build/distributions.
- Refer to Managing Your Drupal Project with Composer at https://glamanate.com/blog/managing-your-drupal-project-composer.
- Refer to Managing your Drupal platform with Drush at https://glamanate.com/blog/managing-your-drupal-platform-drush.
Drupal 8 provides more functionality out-of-the-box than previous versions of Drupal, allowing you to do more with less. However, one of the more appealing aspects of Drupal is the ability to extend and customize.
In this recipe, we will download and enable the Honeypot module (https://www.drupal.org/project/honeypot) and tell Drupal to use the Bootstrap theme (https://www.drupal.org/project/bootstrap). The Honeypot module provides Honeypot and timestamps antispam measures on Drupal sites. This module helps protect forms from spam submissions. The Bootstrap theme implements the Bootstrap frontend framework and supports using Bootswatch styles to theme your Drupal site.
Note
This chapter's recipe will use the standard way of installing modules, by downloading archives available on Drupal.org. As of Drupal 8.2.0, installing modules through Composer has been possible and is the required method for some modules. Installing modules and themes using Composer is covered in the There's more... section of this recipe and is highly recommended.
If you have used Drupal before, note that the folder structure has changed. Modules, themes, and profiles are now placed in their respective folders in the root
directory and no longer under sites/all
. For more information about the developer experience change, refer to https://www.drupal.org/node/22336.
Note
Downloading the example code
: You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you have purchased this book from elsewhere, you can go to http://www.packtpub.com/support and register yourself to have the files emailed directly to you.
Let's install modules and themes:
- Visit https://www.drupal.org/project/honeypot and download the latest 8.x release for Honeypot.
- Extract the archive and place the
honeypot
folder inside themodules
folder, which is inside of your Drupal core installation:
- In Drupal, log in and select the
Extend
option to access the list of available modules. - Using the search text field, type in
Honeypot
. Check the checkbox and click onInstall
.
- Once enabled, search for it again. Clicking on the module's description will expand the row and expose links to configure permissions and module settings:
- Visit https://www.drupal.org/project/bootstrap and download the latest 8.x release for Bootstrap.
- Extract the archive and place the
bootstrap
folder inside thethemes
folder, which is inside your Drupal core installation:
- In Drupal, select the
Appearance
option to manage your Drupal themes. - Scroll down the page and click on
Install and set as default
underBootstrap
to enable and set the theme as default:
The following sections outline the procedure for installing a module or theme and how Drupal discovers these extensions.
Drupal scans specific folder locations to identify modules and themes defined by the .info.yml
file in their directory. The following is the order in which projects will be discovered:
- Their respective core folders (modules, or themes)
- The currently installed profile
- The root
modules
orthemes
folder - The current site directory (default or current domain)
By placing the module inside the root modules
folder, we are allowing Drupal to discover the module and allow it to be installed. When a module is installed, Drupal will register its code with the system through the module_installer
service. The service will check for required dependencies and prompt them to be enabled if required. The configuration system will run any configuration definitions provided by the module on installation. If there are conflicting configuration items, the module will not be installed.
A theme is installed through the theme_installer
service and sets any default configuration by the theme along with rebuilding the theme registry. Setting a theme to default is a configuration change in system.theme.default
to the theme's machine name (in the recipe, it would be bootstrap
).
The following section outlines the procedure for installing a module or theme and includes some additional information for installing.
Although it is not the required way to install an extension, this should become your default method. Why? Because each module is a dependency in your project, and each of those may have its own dependencies. Composer can manage dependencies for you, or you can manage them manually. Your time and capabilities probably will not grow to scale as well as Composer will. Not to mention, it also provides a standard way for PHP projects to interoperate and load classes.
You can get the Honeypot module and Bootstrap using the following two commands:
$ cd /path/to/drupal8 $ composer require drupal/honeypot$ composer require drupal/bootstrap
Here is an example of contributed projects, which require Composer for installation, because they leverage existing libraries in the PHP community at large:
- Drupal Commerce
- GeoIP
- Search API Solr
- Entity Print
As more and more modules integrate existing SDK libraries, the requirement to use Composer will increase.
Modules can be downloaded and enabled through the command line using drush
. The command to replicate the recipe would resemble the following:
$ drush pm-download honeypot$ drush pm-enable honeypot
Note
As of Drush 9, which supports Drupal 8.3+, this section is deprecated. Using Drush to download Drupal core or contributed modules will throw a warning to use Composer instead.
It will prompt you to confirm your action. If there were dependencies for the module, it would ask whether you will like to enable those, too.
One of the substantial changes in Drupal 8 is the module disable and uninstall process. Previously, modules were first disabled and then uninstalled once disabled. This created a confusing process, which would disable its features, but not clean up any database schema changes. In Drupal 8, modules cannot just be disabled but must be uninstalled. This ensures that when a module is uninstalled it can safely be removed from the code base.
A module can only be uninstalled if it is not a dependency of another module or does not have a configuration item in use--such as a field type--which could disrupt the installation's integrity.
Drupal provides the ability to run multiple sites from one single Drupal code base instance. This feature is referred to as multisite. Each site has a separate database; however, extensions stored in modules, profiles, and themes can be installed by all of the sites. Site folders can also contain their own modules and themes. When provided, these can only be used by that one site.
The default
folder is the default folder used if there is no matching domain name.
If you are going to work with multisite functionality, you should have an understanding of how to set up virtual host configurations with your web server. In this recipe, we will use two subdomains under localhost, called dev1
and dev2
.
We will use multisites in Drupal 8 by two subdomains under localhost:
- Copy
sites/example.sites.php
tosites/sites.php
. - Create a
dev1.localhost
anddev2.localhost
folder inside thesites
folder. - Copy the
sites/default/default.settings.php
file intodev1.localhost
anddev2.localhost
assettings.php
in their respective folder:
- Got to
dev1.localhost
and run the installation wizard. - Got to
dev2.localhost
and verify that you still have the option to install a site!
The sites.php
must exist for the multisite functionality to work. By default, you do not need to modify its contents. The sites.php
file provides a way to map aliases to specific site folders. The file contains the documentation for using aliases.
The DrupalKernel
class provides findSitePath
and getSitePath
methods to discover the site folder path. On Drupal's Bootstrap, this is initiated and reads the incoming HTTP host to load the proper settings.php
file from the appropriate folder. The settings.php
file is then loaded and parsed into a \Drupal\Core\Site\Settings
instance. This allows Drupal to connect to the appropriate database.
Let's understand the security concerns of using multisite.
There can be cause for concern if you are using multisite. Arbitrary PHP code executed on a Drupal site might be able to affect other sites sharing the same code base. Drupal 8 marked the removal of the PHP filter (https://www.drupal.org/docs/8/modules/php/overview) module that allowed site administrators to use PHP code in the administrative interface. Although this mitigates the various ways an administrator had easy access to run PHP through an interface, it does not mitigate the risk wholesale. For example, the PHP filter module is now a contributed project and could be installed.
The sites.php
file provides a way to add domain aliases. This can be useful when you use a multisite functionality and need to develop it locally. A simple example would be providing a local.alias
to each site.
If you had example.com
and mycompany.com
as different site directories, the following mapping would allow local.example.com
and local.mycompany.com
to map to those directories:
<?php$sites['example.com'] = 'example.com';$sites['local.example.com'] = 'example.com';$sites['mycompany.com'] = 'mycompany.com';$sites['local.mycompany.com'] = 'mycompany.com';
- Refer to Multisite documentation on Drupal athttps://www.drupal.org/documentation/install/multi-site.
One of the initial hurdles to getting started with Drupal is a local development environment. This recipe will cover how to set up the DrupalVM project by Jeff Geerling. DrupalVM is a VirtualBox virtual machine run through Vagrant, provisioned and configured with Ansible. It will set up all of your services and build a Drupal installation for you.
Luckily, you will only need to have VirtualBox and Vagrant installed on your machine, and DrupalVM works on Windows, macOS X, and Linux.
To get started, you will need to install the two dependencies required for DrupalVM:
- VirtualBox: https://www.virtualbox.org/wiki/Downloads
- Vagrant: http://www.vagrantup.com/downloads.html
Let's set up the DrupalVM project by Jeff Geerling by following these steps:
- Download the DrupalVM archive from https://github.com/geerlingguy/drupal-vm/archive/master.zip.
- Extract the archive and place the project in the directory of your choice.
- Copy
example.drupal.make.yml
todrupal.make.yml
. - Copy
default.config.yml
toconfig.yml
.
- Edit
config.yml
and modify thelocal_path
setting to be the directory where you've placed the DrupalVM project. This will be synchronized into the virtual machine:
vagrant_synced_folders: local_path: /path/to/drupalvm destination: /var/www type: nfs create: true
- Open a terminal and navigate to the directory where you have placed the DrupalVM project.
- Enter the
vagrant up
command to tell Vagrant to build the virtual machine and begin the provisioning process. - While this process is ongoing, modify your host file to provide easy access to the development site. Add the
192.168.88.88 drupalvm.dev
line to your host file. - Open your browser and access http://www.drupalvm.com/.
- Log in to your Drupal site with the username
admin
and passwordadmin
.
DrupalVM is a development project that utilizes the Vagrant tool to create a VirtualBox virtual machine. Vagrant is configured through the project's Vagrantfile
. Vagrant then uses Ansible--an open source IT automation platform--to install Apache, PHP, MySQL, and other services on the virtual machine.
The config.yml
file has been set up to provide a simple way to customize variables for the virtual machine and provisioning process. It also uses Drush to create and install a Drupal 8 site, or whatever components are specified in drupal.make.yml
. This file is a Drush make
file, which contains a definition for Drupal core by default and can be modified to include other contributed projects.
The vagrant up
command tells Vagrant to either launch an existing virtual machine or create one anew in a headless manner. When Vagrant creates a new virtual machine, it triggers the provisioning process. In this instance, Ansible will read the provisioning/playbook.yml
file and follow each step to create the final virtual machine. The only files that need to be modified, however, are the config.yml
and drupal.make.yml
files.
The topic of automating and streamlining a local environment is quite popular right now with quite a few different options. If you are not comfortable with using Vagrant, there are a few other options that provide a server installation and Drupal.
Acquia Dev Desktop is developed by Acquia and can be found at https://docs.acquia.com/dev-desktop2. It is an automated environment installer for Windows and Mac. It is a xAMP stack (or DAMP stack) installer that provides a full Drupal-specific stack that includes Apache, MySQL, and PHP. The Dev Desktop application allows you to create a regular Drupal installation or select from a distribution.
XAMPP - Apache + MySQL + PHP + Perl - is a cross-platform environment installation. XAMPP is an open source project from Apache Friends. XAMPP has partnered with Bitnami (https://bitnami.com/) to provide free all-in-one installations for common applications, including Drupal 8. You can download XAMPP at https://www.apachefriends.org/download.html.
Kalabox is developed by the Kalamuna group and intends to be a robust workflow solution for Drupal development. Kalabox is cross-platform compatible, allowing you to easily work on Windows machines. It is based on the command line and provides application binaries for you to install. You can learn more about Kalabox at http://www.kalamuna.com/products/kalabox/.
- Refer to Chapter 13, The Drupal CLI, for information on makefiles.
- DrupalVM documentation http://docs.drupalvm.com/en/latest/.
- Refer to Drupal.org community documentation on local environment setup at https://www.drupal.org/node/157602.
Drupal 8 ships with two testing suites. Previously, Drupal only supported Simpletest. Now, there are PHPUnit tests as well. In the official change record, PHPUnit was added to provide testing without requiring a full Drupal Bootstrap, which occurs with each Simpletest test. You can read the change record at https://www.drupal.org/node/2012184.
There is currently a PHPUnit initiative active in Drupal core development. The goal is to fully remove the Simpletest framework by Drupal 9. No new Simpletest tests are being written, at least since 8.2. All current tests are currently being converted by contributors. More about the initiative can be found in this issue, https://www.drupal.org/node/2807237, where it is being coordinated.
We will be running tests using the run-tests.sh
test runner. This is a test runner provided by Drupal that supports concurrency and running all of the various test suites. Running tests directly with PHPUnit will be covered in the following There's more... section.
Drupal 8.1.0 introduced the ability to perform JavaScript browser tests. This is powered using PhantomJS (http://phantomjs.org/), which uses a browser emulator powered by the Mink PHP library (http://mink.behat.org/). In order to run the FunctionalJavascript test suite, you must have PhantomJS running.
To install PhantomJS, refer to the official installation instructions at http://phantomjs.org/download.html.
- First, install the
Simpletest
module. Even though you might only want to run PHPUnit, this is a soft dependency for running the test runner script. - Open a command-line terminal and navigate to your Drupal installation directory.
- Next, we will run the test runner script. We will pass it a
url
option so that the Functional tests can run the browser emulator properly. We will also specify the test suites to run. This allows us to skip FunctionalJavascript tests due to PhantomJS not handling concurrency properly in the test runner:
$ php core/scripts/run-tests.sh --url http://localhost--types Simpletest,PHPUnit-Unit,PHPUnit-Kernel,PHPUnit-Functional --concurrency 20 --all
- Running
FunctionalJavascripts
tests require PhantomJS to be running. Since PhantomJS prints output to the terminal, open a new tab or terminal and run the following command:
phantomjs --ssl-protocol=any --ignore-ssl-errors=true vendor/jcalderonzumba/gastonjs/src/Client/main.js 8510 1024 768
- With PhantomJS running, we can now execute the FunctionalJavascript test suite:
php core/scripts/run-tests.sh --url http://localhost--types PHPUnit-FunctionalJavascript --concurrency 1 --all
- Review test output from each test suite run.
The run-tests.sh
script has been shipped with Drupal since 2008, then namedrun-functional-tests.php
. This command interacts with the test suites in Drupal to run all or specific tests and sets up other configuration items.
There are several different test suites that operate in specific ways:
- Simpletest: The deprecated test system, full bootstraps and installs Drupal and uses its own browser emulator pattern using curl and XPath.
- PHPUnit-Unit: Unit tests backed by PHPUnit. These are intended to test specific classes and not interact with the database.
- PHPUnit-Kernel: Integration-level tests backed by PHPUnit. It is a test that has the ability to install schema and configuration to the database, minimally bootstrapping Drupal for basic integration testing.
- PHPUnit-Functional: Functional tests are tests that require a fully bootstrapped Drupal and provide browser emulation via Mink. These can be considered a direct replacement of Simpletest tests but leveraging third-party testing libraries.
- PHPUnit-FunctionalJavascript: Functional tests that have the ability to interact with PhantomJS in order to test JavaScript, such as AJAX operations and specific user interface interactions.
The following are some of the useful options:
--help
: This displays the items covered in the following bullets--list
: This displays the available test groups that can be run--url
: This is required unless the Drupal site is accessible throughhttp://localhost:80
--sqlite
: This allows you to run tests without having Drupal installed--concurrency
: This allows you to define how many tests run in parallel
We will now discuss more techniques and information for running Drupal's test suites.
The run-tests.sh
isn't actually a shell script. It is a PHP script--which is why you must execute it with PHP. In fact, within core/scripts
, each file is a PHP script file meant to be executed using the command line. These scripts are not intended to be run through a web server, which is one of the reasons for the .sh
extension.
There can be issues with PHP across platforms that prevent providing a shebang line to allow executing the file as a normal bash
or bat
script. For more information, refer to this Drupal.org issue at https://www.drupal.org/node/655178.
With Drupal 8, tests can also be run from SQLlite and no longer requires an installed database. This can be accomplished by passing the sqlite
and dburl
options to therun-tests.sh
script. This requires the PHP SQLite extension to be installed.
Here is an example adapted from the DrupalCI test runner for Drupal core. DrupalCI is the continuous integration service, which runs on Drupal.org for all submitted patches and commits:
php core/scripts/run-tests.sh --sqlite /tmp/.ht.sqlite --die-on-fail --dburl sqlite://tmp/.ht.sqlite --all
Combined with the built-in PHP web server for debugging, you can run test suites without a full-fledged environment.
Each example so far has used the all
option to run every Simpletest
available. There are various ways to run specific tests:
--module
: This allows you to run all the tests of a specific module--class
: This runs a specific path, identified by a full namespace path--file
: This runs tests from a specified file--directory
: This run tests within a specified directory
Drupal 8 has seen a surge in test coverage for both Drupal core and contributed projects, most likely due to PHPUnit adoption. In response to this, the author has written a PhpStorm plugin called Drupal Test Runner that simplifies executing the run-tests.sh
script runner.
The plugin's page can be found at https://plugins.jetbrains.com/plugin/8384-drupal-test-runner, and it's public source code can be found at https://github.com/mglaman/intellij-drupal-run-tests.
With Drupal 8 came a new initiative to upgrade the testing infrastructure on Drupal.org. The outcome was DrupalCI. DrupalCI is open source and can be downloaded and run locally. The project page for DrupalCI is https://www.drupal.org/project/drupalci.
The test bot utilizes Docker and can be downloaded locally to run tests. The project ships with a Vagrant file that allows it to be run within a virtual machine or locally. Learn more on the testbot's project page at https://www.drupal.org/project/drupalci_testbot.
- Refer to the PHPUnit manual at https://phpunit.de/manual/4.8/en/writing-tests-for-phpunit.html.
- Refer to the Drupal PHPUnit handbook at https://drupal.org/phpunit.
- Refer to Running tests from the command line at https://www.drupal.org/node/645286.
- Refer to Commerce 2.x: Unit, Kernel, and Functional Tests Oh My! Authors blog post and tutorial for running tests in Drupal 8 for Drupal Commerce at https://drupalcommerce.org/blog/45322/commerce-2x-unit-kernel-and-functional-tests-oh-my.