Skip to content

PHPUnit

The phpunit jobs run the PHPUnit tests defined by your module, including Functional, FunctionalJavascript, Kernel and Unit tests. You have a choice of two ways that the tests can be executed:

  • Using the phpunit binary directly and running the tests in sequential mode. This is the default, but you can specify it using:
variables:
  _PHPUNIT_CONCURRENT: 0
  • Using the Drupal core script run-tests.sh to execute the tests in parallel mode:
variables:
  _PHPUNIT_CONCURRENT: 1

Using phpunit binary directly (non-concurrent mode)

This is the default option. The tests will be run calling the vendor/bin/phpunit binary directly and in a sequential order. As there is no concurrency, the tests are likely to take longer to run.

You can use the _PHPUNIT_EXTRA variable to add extra options to the phpunit binary. For example:

variables:
  _PHPUNIT_EXTRA: "--debug"

TestDox

An example of one of the phpunit-only options is TestDox. If you want nicer CI terminal output you can set or add the option --testdox to the variable _PHPUNIT_EXTRA. The output will change from the typical

.............. (14/14)

to a more detailed output showing each test name and class, for example:

Admin Pages (Drupal\Tests\api\Functional\AdminPages)
 ✔ Admin pages
Api Access (Drupal\Tests\api\Functional\ApiAccess)
 ✔ Access
 ✔ Branch objects
 ...

Note that this option conflicts with the Drupal HtmlOutputPrinter printer and, if used, no .html artifacts will be generated after the run.

Running a subset of the tests

There may be times when you temporarily only need to run one or two tests, instead of the whole test suite. This can be achieved using:

variables:
  _PHPUNIT_EXTRA: "--filter='/thisTest|thatTest/' "

The --filter parameter is only valid when running the phpunit binary directly.

Using run-tests.sh core script (concurrent mode)

This script is included in Drupal core and leverages concurrency and also runs the tests in the same way that Drupal core tests are run. As there is concurrency, the job should run quicker than with the sequential option.

To enable concurrent mode set the variable _PHPUNIT_CONCURRENT to 1. You can set the _CONCURRENCY_THREADS variable as well to tweak the concurrency level used by run-tests.sh. The default value is set to 32.

In this case, the _PHPUNIT_EXTRA variable will contain options compatible with the run-test.sh script. You can also add parallel or parallel:matrix options to the job definition, to split out the tests into multiple jobs running in parallel.

If you want to split evenly the tests that are run in each parallel job, you can do it like this:

variables:
  _PHPUNIT_EXTRA: "--ci-parallel-node-index $CI_NODE_INDEX --ci-parallel-node-total $CI_NODE_TOTAL"

phpunit:
  parallel: 3

Variants

The phpunit job has multiple variants to check previous, current and future versions of Drupal. See the OPT_IN variables for more details.

If you want to tweak the value of the options per variant, you can do something like this:

variables:
  _PHPUNIT_EXTRA: "value for all variants unless overriden..."

phpunit (next major):
  variables:
    _PHPUNIT_EXTRA: "value for next major variant only"

PHPUnit versions

Drupal 10 uses PHPUnit 9, whereas Drupal 11 uses PHPUnit 10. Because of this, not all phpunit options are valid in both versions. If you use _PHPUNIT_CONCURRENT: 1, then run-tests.sh takes care of these cases for you. However, if you use _PHPUNIT_CONCURRENT: 0, you might need to adapt the options per variant as shown in the previous section.

If you do not provide a PHPUnit configuration file in your module, the default file from core/phpunit.xml will be used.

If you do provide a PHPUnit configuration file in your module, you might need to provide a different one depending on the PHPUnit version. You can achieve it like this (where phpunit9.xml and phpunit10.xml are files in the root of your repository):

variables:
  _PHPUNIT_EXTRA: '-c $CI_PROJECT_DIR/phpunit9.xml'

phpunit (next major):
  variables:
    _PHPUNIT_EXTRA: '-c $CI_PROJECT_DIR/phpunit10.xml'

The variants inherit customizations made in the phpunit job. If you don't want these to propagate to the variants, you could extend the variants from the .phpunit-base job, like this:

phpunit (next major):
  extends: !reference [.phpunit-base]

Web driver versions

Tests on Drupal 11 and above will use Selenium and the latest Chrome W3C-compliant browser. Tests on Drupal 10 and below will continue to use the legacy Chrome driver which is not W3C-compliant. If your javascript tests at Drupal 11 still need to use the legacy driver, add the following lines to a PHPUnit job to override the default behavior:

  # Set the services and web driver variables to the legacy versions.
  services:
    - !reference [ .with-database ]
    - !reference [ .with-chrome-legacy ]
  variables:
    MINK_DRIVER_ARGS_WEBDRIVER: $MINK_DRIVER_ARGS_WEBDRIVER_LEGACY

Deprecations

The variable SYMFONY_DEPRECATIONS_HELPER is set to disabled by default, so that warnings and deprecations are not reported.

You can mirror what core does by using the Core .deprecation-ignore.txt file. This will only ignore the deprecations that Core ignores:

phpunit (next minor):
  variables:
    SYMFONY_DEPRECATIONS_HELPER: "ignoreFile=$CI_PROJECT_DIR/$_WEB_ROOT/core/.deprecation-ignore.txt"

If your project has its own phpunit.xml(.dist) file and you are testing with Drupal 10 (which uses PHPUnit 9), running PHPUnit directly via _PHPUNIT_CONCURRENT: 0, your file will need to contain the <listener class="\Drupal\Tests\Listeners\DrupalListener"> class in order to get deprecation warnings. This is not needed for Drupal 11 (which uses PHPUnit 10).

If you want to report other deprecations, like third party ones, you can create your own deprecations file and call it like this:

phpunit:
  variables:
    SYMFONY_DEPRECATIONS_HELPER: "ignoreFile=./.local-deprecation-ignore.txt"

Finally, and if you are using a Drupal core version that comes with PHPUnit 10 or above (this would be Drupal 11 or above), you can also set the flag --fail-on-deprecation in the _PHPUNIT_EXTRA variable. This is only needed if you are running the tests in non-concurrent mode (see above). The code would look like this:

variables:
  _PHPUNIT_EXTRA: '--fail-on-deprecation'