12/1/2021

Phpunit Drupal 8

Phpunit Drupal 8
  1. Phpunit Version Drupal 8
  2. Phpunit Drupal 8 Login
  3. Drupal 8 Install Phpunit
  4. Phpunit Drupal 8 Free
  5. Phpunit Drupal 8 Download

8.1.x vendor/phpunit/phpunit/src/TextUI/Command.php PHPUnitTextUICommand::main; 8.2.x vendor/phpunit/phpunit/src/TextUI/Command.php PHPUnitTextUICommand::main. Name Modifiers Type Description Overrides; PHPUnitUtilConfiguration:: $document protected: property: PHPUnitUtilConfiguration:: $filename protected: property.

Updated: 2021-06-04

Setting up Lando and Drupal to run PHPUnit tests can be tricky. This post attempts to break it down and provides a guide to getting set up.

At the end of the post is a working .lando.yml file that you can copy/paste from to extend your usual Lando set up.

A bit about Drupal tests

Drupal 8 and 9 use PHPUnit to run various types of test. This post won't go into detail about writing tests but instead focuses on getting an environment capable of running tests.

Each time a test is run a new environment is set up, including the database, the tests are run and then the test environment is destroyed. While developing a Drupal module or site it can be useful to write tests and run them in your development environment. Instead of needing to run two MySQL databases side by side, it can be sufficient to have your test environment build the Drupal site using SQLite as the backend database. This allows you to keep the two environments from clashing but still have them run in the same containers for ease of use.

Lando set up

Lando is a very nicely written bit of software which acts as a wrapper over docker-compose and provides a slightly simpler format to help you get a development environment up and running.

A very basic .lando.yml configuration file for Drupal 8 looks like this:

This will give you a set of containers capable of running Drupal 8. At the time of writing PHP 7.2 has the best compatibility with Drupal 8’s version of PHPUnit and dependencies but it is possible to upgrade packages for compatibility.

To get started create a .lando.yml file in a directory of your choosing with the content above. You might want to change the name value or add further config. The location where you create the .lando.yml file will be the project root (not the web root) and we’ll run most of the commands from this location.

Bring the containers up so we have access to lando’s composer and php generally:

Drupal 9 installation

To start with we'll install Drupal using the current recommended approach. Due to the current directory already having our .lando.yml file it in composer won't be able to install into it. Instead we'll install into a temp directory and then mv everything out of it into our current directory and clean it up afterwards:

The drupal/recommended-project does not include the require-dev section that comes with the git installed version, so we need to add the development packages ourselves:

Drupal 9

Drupal 8

Also for Drupal 8, if you are running PHP 7.3 you'll need to update a few packages:

Configure Lando for PHPUnit tests

We now need to configure Lando with some environment variables which Drupal's PHPUnit implementation will make use of.

Install phpunit drupal 8

First of all copy the phpunit.xml.dist file into the project root:

We'll leave the defaults for most of the values in that file except for where to find the bootstrap.php file. This should be changed to the path in the Lando container, which will be /app/web/core/tests/bootstrap.php. This can be done with sed:

All the other variables we will leave as default as we'll be passing in environment variables through Lando to the containers which will take precedence over the values in the phpunit.xml file.

Next edit the .lando.yml file and add the following:

This does three things:

  1. Adds environment variables to the appserver container (the one we’ll run the tests in).
  2. Adds a new container for the chromedriver image which is used for running headless javascript tests (more on that later).
  3. A tooling section which adds a test command to lando to run our tests.

Important!

After updating the .lando.yml file we need to rebuild the containers with:

Running tests

Phpunit Version Drupal 8

At this point we’re actually ready to run existing tests. Even though Drupal hasn't been installed it is possible to run tests as tests are always run in a separate database. We defined this database in the SIMPLETEST_BASE_URL environment variable and specified an SQLite database, stored in the containers /tmp/ directory. This database is destroyed after each test to ensure a clean environment.

Lets run a single test from the color module:

This should produce the following output:

Success! You've run your first PHPUnit functional (browser) test in a Lando container.

It will have taken a little while to run, maybe around 20 seconds. This is because a full Drupal site is installed temporarily and specifically for this test.

Running a JavaScript test

By installing the chromedriver image in a container we can also run headless browser tests with JavaScript. Let’s try one:

You should again see similar output:

Running a Kernel test

Finally lets run a quick kernel test which doesn't run in a browser:

Kernel tests install an empty database and so the bootstrap phase is very quick compared to a full installation and the test will execute much quicker.

Wrap up

By following these steps you’ve:

  1. Set up a set of Docker containers using Lando to host the Drupal 8 codebase and downloaded the needed PHP packages.
  2. Modified the .lando.yml config to add environment variables and the chromedriver container
  3. You've run three PHPUnit tests, the first an internal browser test using Mink, the second a headless chromedriver based test and the third a kernel test without a headless browser.

You can now install Drupal if you want, using your usual methods. You'll need the Lando database container's credentials (or supply your own) and begin developing as you normally would. In addition you now have access to PHPUnit tests and can start writing and running your own tests as you need.

Complete .lando.yml file example

A more complete looking .lando.yml might look like this:

Time to share some experiences with getting something up and running. This time getting PHPUnit to work under Drupal8 on Windows.

I started reading PHPUnit in Drupal and the PHPUnit manual, downloaded the PHPUnit phar file and performed some PHPUnit only tests until things started to work. The examples on the PHPUnit website where a bit flawed especially the one with the CsvFileIterator class as it turns out PHP’s fgetcsv() nicely returns integer values yet the testAdd method is called with the integer converted to strings.

I had to modify the example to

public function testAdd($a, $b, $expected): void
{
// additionProvider returns integers, but PHPUnit’s invocation
// of testAdd() seems to receive strings.
// Note: The csv file should have a trailing crlf.
$this->assertSame($expected+0, $a+0 + $b+0);
}

in order to force a conversion to numbers again so the assertion can do it’s job.

Another observation is that annotations are important. For example adding

@covers <something>

to a methods comment silences the ‘Risky’ test warnings. Finally it’s important to create a phpunit.xml file in the folder from where you start PHPUnit to run the tests. Running the tests is a matter of a command alike:

php phpunit.phar <relative path where to look for tests>

The CsvFileIterator example I got working by specifying the CsvFileIterator.php as bootstrap in the phpunit.xml file (a workaround). An alternative might be adding a line to the Unit Test alike:

include(dirname(__FILE__).”/../../src/CsvFileIterator.php”);

assuming the relative path to CsvFileIterator.php file is correct.

Getting things to run under Drupal8 was a different adventure.

I started with using the PHPUnit version I downloaded (the latest version) and it looked promising. I was able to run my standalone examples after adding them into a Drupal custom module I planned to write tests for.

The problems started when I wanted to access a simple class method in the module. First it looked simple as a namespace issue (understandable as the test suite wasn’t going to load Drupal code without it being correct). Using the examples on the Drupal8 website I corrected namespaces and moved the test suite into the correct location.

The Unit Test namespace should look as:

namespace DrupalTests<custom module>Unit;

The Unit Test class documentation should look as:

/**
* @coversDefaultClass Drupal<custom module><custom module class>
* @requires module <custom module>
* @group Unit
*/

The test class should extend UnitTestCase instead of TestCase (something I discovered later). The test class location should be:

modules<custom module>testsUnitControllerServiceTest.php

Note the Unit in the path/namespace and the base class depends on the type of test being implemented.

Finally it’s important to copy the phpunit.xml.dist file out of the core folder and rename it to phpunit.xml. If you leave the phpunit.xml file in the core folder it will get deleted when the core is updated with composed. Finally edit the phpunit.xml file, correct the path to the Bootstrap.php file to bootstrap=”core/tests/Bootstrap.php” and uncomment the ini tags and specify the correct values for your Drupal8 installation.

But even with this all done, calling a method on a custom module class still failed miserably with some vague messages about missing classes in PHPUnit. Searching for them which normally works to get a clue about what’s wrong totally failed this time, suggesting nobody had this issue and the missing classes just did not exist.

After re-reading quite some webpages I came across this text on the first page I read starting this adventure:

“We use multiple versions of PHPUnit in the DrupalCI on drupal.org. E.g. on PHP 5.5, 5.6, 7.0 and 7.1 we use PHPUnit 4.8. On PHP 7.2 we use PHPUnit 6.5. It is discouraged to use PHP versions which are out-of-life on production (documentation about supported PHP versions).”

Although I though it was a long shot (I was using PHP 7.3 for example), I started looking into how to get an older version of PHPUnit installed.

composer require –dev phpunit/phpunit ^6.5

Although I’m no fan of composer this finally worked. Installing a newer version using

composer require phpunit/phpunit

gets you into trouble when downgrading as one of the dependencies prevents a direct downgrade without first removing it.

Finally my test code creating a class from the custom module and invoke a simple method worked:

The command:

php vendorphpunitphpunitphpunit .modules<custom module>

from the Drupal8 root folder now nicely executes the test:

Phpunit Drupal 8 Login

Phpunit

<?php declare(strict_types=1);

Drupal 8 Install Phpunit

namespace DrupalTests<custom module>Unit;

Phpunit Drupal 8 Free

use DrupalTestsUnitTestCase;
use Drupal<custom module>FormStudyMessage;

Phpunit Drupal 8 Download

/**
* @coversDefaultClass Drupal<custom module>StudyMessage
* @requires module <custom module>
* @group Unit
*/
final class ControllerServiceTest extends UnitTestCase {
$service = new StudyMessage();
$this->assertIsObject($service);
$this->assertInstanceOf(StudyMessage::class, $service);
fwrite(STDOUT, $service->getFormId() . “n”);
$this->assertSame($service->getFormId(),”XYZ”);
}