Let's write somewhat strict unit tests in a Drupal module. By the end of this tutorial, you will be able to:
- Understand what makes a unit test different from other types of tests.
- Determine the specifications of a unit test.
- Use mocking to isolate units under test, and to force code flow to achieve high coverage.
We'll start out with a brief introduction to unit tests. Then we'll look at a contrived example of a Drupal controller class for illustration purposes. Next, we'll test two units of this controller class, each requiring different mock styles.
In this gentle introduction to testing, we'll walk through what testing is and why it's important to your project. Then we'll define some terms you'll be likely to see while working with tests so that we're all on the same page. After reading through this tutorial you'll understand enough of the basic vocabulary to get started running (and eventually writing) tests for your Drupal site.
The testing suite for the Drupalize.Me site uses a different strategy for functional JavaScript testing. We use a tool called Nightwatch.js that allows us to write our tests in JavaScript that runs commands against a web browser. This browser automation allows us to test the types of interactions that a typical user of our website might encounter. It also allows us to test JavaScript code using JavaScript, and execute our tests in different browsers. In this tutorial we'll take a look at how to set up Nightwatch.js, and what the syntax looks like for a couple of basic tests.
In order for Drupal to be able to locate and run the tests you create, the files need to be put in the correct place. In this tutorial, we'll take a look at the different types of test frameworks that are included along with core. We'll also see how Drupal expects our test files to be organized so that the test runners can find them.
When running tests with PHPUnit we need to specify a phpunit.xml file that contains the configuration that we want to use. Often times (and in much of the existing documentation) the recommendation is to copy the core/phpunit.xml.dist file to core/phpunit.xml and make your changes there. And this works fine, until something like a composer install
or composer update
ends up deleting your modified file. Instead, you should copy the file to a different location in your project and commit it to your version control repository.
In this tutorial we'll:
- Learn how to move, and modify, the phpunit.xml.dist file provided by Drupal core
- Understand the benefits of doing so
- Demonstrate how to run
phpunit
with an alternative configuration file
By the end of this tutorial you should be able to commit your phpunit.xml configuration file to your project's Git repository and ensure it doesn't get accidentally deleted.
In this tutorial, we'll run tests in several different ways using the PHPUnit tools available in Drupal. We'll learn about various environment variables you'll need to supply to the test runner depending on which type of test you're running. And we'll learn various ways to get reports on the test results. By the end of this tutorial, you should understand how to run Drupal tests using PHPUnit.
Drupal core comes with a run-tests.sh script to help with running tests. This script has some distinct advantages over running tests directly via PHPUnit. It runs all tests in their own separate process, and can therefore handle PHP fatal errors without killing the test run. It's also the mechanism that the Drupal CI tools use to run tests; so, it can be handy when debugging tests that are failing on Drupal.org.
In this tutorial we'll:
- Look at the available options for the core run-tests.sh script
- Go through some examples of running tests using run-tests.sh
By the end of this tutorial you'll know how to run your tests using run-test.sh.
In this tutorial, we'll walk through the process of setting up a functional test. Then, we'll learn how to run it using two different test runners. This setup process allows us to be sure we're not getting false positives from the test runners. We'll be working on a functional test, but these techniques apply with minimum modification to all the Drupal PHPUnit-based tests.
By the end of this tutorial, you should be able to set up and run functional tests in Drupal using two different test runners.
This tutorial will clarify some basic ideas about software testing. We'll give some strategies for testing and illustrate types of tests and when and why you'd use them. This document is written with Drupal in mind, but the concepts apply for other development environments you'll encounter as well. The tools will be different, but the ideas apply universally. By the end of this tutorial, you should understand what testing is for and how different types of tests support different purposes and outcomes.
In order to run functional tests that require JavaScript be executed for the feature to work, the tests need to be run in a browser that supports JavaScript. This is accomplished by using the WebDriver API in combination with an application like ChromeDriver or Selenium, which can remotely control a browser.
The exact setup for running functional tests is dependent on your development environment. We'll walk through a couple of common examples including using Docker (via DDEV) and stand-alone applications.
In this tutorial we'll:
- Learn how to install and run ChromeDriver and other necessary tools either in a Docker environment, or locally.
- Configure the relevant PHPUnit environment variables so they contain values appropriate for our specific environment.
- Execute Drupal's functional JavaScript tests via the
phpunit
command.
By the end of this tutorial you should be able to install the applications required to run functional JavaScript tests in a browser, and know how to configure PHPUnit to make use of them.
Drupal's Breakpoint module defines a "breakpoint" plugin type that modules or themes can implement via a breakpoints configuration file. So, in order to make their breakpoints discoverable, themes and modules define their breakpoints in a THEME-OR-MODULE.breakpoints.yml file located in the root of their directory.
In this tutorial, you'll learn about the structure of a breakpoints configuration file and why you would want to use one. We’ll cover the kinds of metadata you can include in a breakpoint file, including key, label, mediaQuery, weight, multipliers, and breakpoint group. Throughout, we'll look at some examples of breakpoint configuration files available in Drupal themes and modules.
You've got a slick responsive theme for your Drupal site that's been implemented in CSS using media queries. But the content and images on your site will regularly be updated and you want to use the Responsive Images module to create responsive image style field formatters that you can apply to image field display settings.
In this lesson, we'll review the concepts of breakpoints and media queries so that you can better understand what's going on when you encounter them in non-CSS file contexts like configuration forms for responsive image styles or breakpoint YAML files.
By the end of this tutorial, you should have an understanding of what breakpoints are, how they are expressed in media queries, and how they are relevant in the context of Drupal.
Core Themes: Bartik
FreeBartik is a core theme in Drupal. As a default theme for Drupal, it serves as an instructive example of a well-developed responsive theme. In this tutorial, we'll tour and explore Bartik, identify its primary features, and explain the use case for the Bartik theme and what you can learn from it.
Core Themes: Stark
FreeStark is one of the themes bundled with Drupal. It is intentionally bare bones and its purpose is to help Drupal theme and module developers get to the heart of Drupal's system templates. In this tutorial, we'll explore Stark and its primary features and discuss the various reasons for utilizing the Stark theme.
As we learned in the What Is a Breakpoints YAML file? tutorial, modules and themes can expose their site's CSS breakpoints and media queries to other Drupal modules and themes by implementing a breakpoints YAML file. In that tutorial, you also learned about the structure of a breakpoints configuration file and why you'd want to create one. In this tutorial, we’ll walk through the process of creating an example breakpoints file step-by-step.
By the end of this lesson, you should be able to create a working breakpoints YAML file in a theme or module. We'll test it out by enabling Drupal's Responsive Image module, where we'll be able to see it listed in the configuration form for creating a new responsive image style.
In Drupal's Appearance UI, all themes get a theme settings form. As a theme developer, you can customize the theme settings form, enabling site administrators to have more control over the appearance of the theme.
In this tutorial, we'll show you how to add admin-configurable settings to your theme. In the process of doing this, we'll use a variety of theme and module development skills and assume you have some familiarity with using Drupal's Form API, Configuration API, and theme system (see Prerequisites).
By the end of this tutorial, you will be able to provide custom theme settings that an administrator can use to modify the appearance of the theme.
The Responsive Image module provides a process for transforming images uploaded through image fields into responsive images. This is accomplished through the configuration of responsive image styles. The configuration form for adding and editing responsive image styles is quite extensive. In this tutorial, we'll go through this form and learn what each option entails. By the end of this lesson, you should have a good understanding of the various options in the responsive image style configuration form.
You might already be familiar with image styles in Drupal. Image styles are a popular and commonly used feature of Drupal because they enable your site's content creators to upload an image once, but have it displayed at various sizes and resolutions depending on its context. Image styles are configured and then applied to an image field's display settings, whether using view modes, Views field settings, or other contexts. Responsive image style field formatters are applied in the same exact way, but the process of creating responsive image styles is a bit different.
Using responsive image styles as image field formatters enables your Drupal site to produce specific HTML markup for images so that either:
- The browser can choose an appropriately sized image source, given the size of the user device's viewport size
- You can dictate to the browser which image sources to use at different breakpoints.
In the first case, the resulting markup uses the srcset
and sizes
attribute in an <img>
element. In the second case, <picture>
and <source>
elements are generated in conjunction with the <img>
tag.
It is also possible to create a responsive image style that just provides alternate images depending on the display-density (i.e. 1.5x or 2x) of the user device.
In this tutorial, we'll look at three use cases for responsive images, how those use cases are handled in HTML, and how they can be handled using Drupal's Responsive Image module. By the end of this tutorial, you should be ready to create a responsive image style appropriate for your Drupal site.
In this tutorial, we're going to add a responsive image style to an image field on the Article content type. This will add the srcset
and sizes
attributes to the output <img>
element, providing media conditions, width descriptors, and a set of image sources for the browser to choose from, depending on the user device's viewport size.
This solution, especially when used in conjunction with CSS, will provide flexible, fluid, and faster-loading images for your site, and will work for probably 80% of use cases. It does not provide "art direction", that is, making cropping, aspect ratio, or orientation changes to an image. This solution also provides for different display-densities, like 1.5x and 2x image sources without the need for display-density descriptors.
Another benefit of this solution is that it uses the Responsive Image module's breakpoint configuration file, so there is no need for you to create a breakpoint file in your theme to implement this flavor of responsive image style.
If you want to create a link to an internal page in a Twig template--and there's not already a variable in the template that contains the URL you want to link to--you'll need to determine the route of the thing you want to link to and then use the Twig url()
or path()
functions to generate appropriate URLs. In most cases when you want to create a link to an entity that is being output by the current template there's an existing helper variable to use. For example, in a node.html.twig template file there's a url
variable that points to the current node. For other scenarios, like hard-coding a link to the /about page, you'll need to do a little more work.
In this tutorial, we'll:
- Get the absolute URL value
- Get the relative path value
- Generate HTML for a link
- Get the URI to a file, like an image in the Media library
- Get the active theme path
By the end of this tutorial you should be able to create links to any internal page via Twig.