Skip to main content

PHPUnit

Vortex uses PHPUnit as a framework for unit, kernel, functional and functional JavaScript testing. PHPUnit tests verify that individual components work correctly in isolation and when integrated with Drupal's systems.

Vortex provides full PHPUnit support, including configuration in phpunit.xml based on Drupal core's core/phpunit.xml.dist to allow customizing the test suite per project.

Usage

# Run all PHPUnit tests (all suites)
ahoy test
# Run only Unit tests
ahoy test-unit
# Run only Kernel tests
ahoy test-kernel
# Run only Functional tests
ahoy test-functional
# Run only Functional JavaScript tests
ahoy test-functional-javascript
# Run specific test file
ahoy test tests/phpunit/ExampleTest.php
# Run tests with filter
ahoy test -- --filter=testMethodName
# Run tests tagged with a `@group group_name` annotation
ahoy test -- --group=group_name

Writing tests

Skipping tests

Add a @group skipped annotation to a test class or method to exclude it from the test run - phpunit.xml excludes the skipped group by default:

/**
* @group skipped
*/
public function testSomethingToSkip(): void {
// This test will be skipped
}

Boilerplate

Vortex provides unit, kernel, functional and functional JavaScript tests boilerplate for custom modules, themes and scripts.

These boilerplate tests run in the continuous integration pipeline when you install Vortex and can be used as a starting point for writing your own.

Drupal settings tests

Vortex provides Drupal settings tests to check that Drupal settings are correct based on the environment type the site is running: with the number of custom modules multiplied by the number of environment types, it is easy to miss certain settings which may lead to unexpected issues when deploying a project to a different environment.

They are intended to be used in your site and kept up-to-date with the changes made to the settings.php file.

Continuous integration pipeline configuration tests

Vortex provides CircleCI configuration tests to check that the continuous integration configuration is correct. They are intended to be used in your site and kept up-to-date with the continuous integration configuration.

For example, there are tests for regular expressions used to filter the branches and tags before they are deployed to the hosting environment.

Project conventions

For project-specific test writing conventions (test class structure, base classes, data providers, test data conventions), see your project's docs/testing.md file.

The docs/testing.md file is scaffolded when you install Vortex and should be maintained by your project team to document agreed-upon testing practices.

Configuration

See configuration reference.

All global configuration takes place in the phpunit.xml file in the project root. It configures:

  • Test suite directories and naming patterns
  • Bootstrap file for Drupal integration
  • Environment variables for test execution
  • Code coverage settings

By default, PHPUnit will run tests for custom modules and themes, Drupal settings, and the shipped CircleCI configuration test.

Test suites

PHPUnit tests are organized into test suites defined in phpunit.xml:

  • unit - fast tests of isolated PHP classes without a Drupal bootstrap
  • kernel - tests with a partial Drupal bootstrap (database and core services)
  • functional - tests with a full Drupal bootstrap and browser simulation
  • functional-javascript - tests with a full Drupal bootstrap and a real browser (Chrome via Selenium) for JavaScript interactions

The recommended way of adding test targets is via test suites:

<testsuite name="unit">
<directory>my/custom/dir/*/tests</directory>
</testsuite>

Chrome session flags

Functional JavaScript tests use a Chrome browser running in the selenium/standalone-chromium container. The following flags are passed via MINK_DRIVER_ARGS_WEBDRIVER in phpunit.xml to ensure stable and deterministic test execution:

FlagPurpose
--disable-extensionsPrevents interference from browser extensions
--disable-popup-blockingAllows tests to open popups without being blocked
--disable-translatePrevents the translation bar from appearing on non-English pages
--force-prefers-reduced-motionDisables CSS animations and transitions for test stability
--test-typeSuppresses error dialogs and crash recovery prompts
--window-size=1920,1080Sets a deterministic viewport size for consistent screenshots

The w3c: true option is required for compatibility with Selenium 4.

Bootstrap

The custom tests/phpunit/bootstrap.php file runs before tests to:

  1. Set BROWSERTEST_OUTPUT_BASE_URL from the LOCALDEV_URL environment variable so that HTML output links are accessible from the host machine.
  2. Create the web/sites/simpletest/browser_output directory required by the HtmlOutputLogger extension before it initializes (see Drupal core issue #2992069).

Reports

PHPUnit writes a JUnit XML report to .logs/test_results/phpunit/phpunit.xml.

Coverage

PHPUnit is configured to generate code coverage reports. The reports are stored in .logs/coverage/phpunit/cobertura.xml as Cobertura XML, suitable for automated coverage assessment, and in .logs/coverage/phpunit/.coverage-html as an HTML coverage report, useful for visual report assessment during test development.

Ignoring lines from coverage

Sometimes it is necessary to ignore lines from coverage. For example, when testing a module that uses a third-party library, it is not necessary to test the library itself.

To ignore a method from coverage, add @codeCoverageIgnore annotation to the method docblock.

/**
* @codeCoverageIgnore
*/
public function myMethod() {
// ...
}

To ignore a line from coverage, add @codeCoverageIgnoreStart and @codeCoverageIgnoreEnd annotations before the first and after the last line.

// @codeCoverageIgnoreStart
$a = 1;
$b = 2;
// @codeCoverageIgnoreEnd

Continuous integration

In the continuous integration pipeline, PHPUnit runs on the first container only, see Test parallelism. The pipeline runs tests with coverage by default and stores the coverage reports as artifacts, and collects the JUnit report to track test performance and stability.

Coverage threshold

CI enforces a minimum coverage threshold. If coverage falls below the threshold, the build fails. Set VORTEX_CI_CODE_COVERAGE_THRESHOLD to configure the minimum percentage (default: 90).

Coverage reports are posted as PR comments automatically. Each new report replaces the previous one - older comments are minimized to keep the PR timeline clean. The comment includes a header indicating the CI source (GitHub Actions or CircleCI). Set VORTEX_CI_CODE_COVERAGE_PR_COMMENT_SKIP to 1 to disable.

Ignoring failures

Set the VORTEX_CI_PHPUNIT_IGNORE_FAILURE environment variable to 1 to ignore failures. The tool still runs and reports violations. See Ignore tool failures.