Skip to main content
Version: v1

Testmode

Testmode keeps live and generated content out of Behat assertions. While test mode is on, it filters the listings in the views you register down to the items whose title, name, or email matches a test pattern. A scenario then sees only what it created, even on a site full of demo pages or a copy of production.

This page is for developers writing Behat tests on a project built from Vortex. It shows how to register a view with Testmode and how to turn test mode on for a scenario. The module documentation is the reference for its full API.

How it works​

Testmode filtering relies on 3 conventions:

  • Test content created in Behat features has titles that start with [TEST].
  • The views to filter are registered in the testmode.settings configuration.
  • Behat scenarios tagged with @testmode turn filtering on before they run and off after they end.

While filtering is on, the registered views show only content that matches the test patterns, such as [TEST% for node titles.

Testmode keeps its on/off flag in the state system, so switching it never touches configuration. While it's on, users with the administer site configuration permission see a warning on every page. The warning starts with Test mode is enabled. and links to the Testmode settings at /admin/config/development/testmode. That warning is how you'll spot a test run that stopped before switching test mode off.

To turn test mode off by hand, use 1 of the following:

  • On the Testmode settings page, select Disabled under Test mode, then click Save configuration.
  • From code, call Testmode::getInstance()->disableTestMode().
  • With Drush, delete the state flag, then invalidate the testmode:views cache tag that Testmode adds to the views it filters, so their cached listings are rebuilt.

The Drush route uses the following commands:

ahoy drush state:delete testmode.enabled
ahoy drush cache:tags testmode:views

The second command reports Invalidated tag(s): testmode:views. Confirm that the warning no longer appears on the next page you load.

Configuration​

Testmode is configured through the testmode.settings configuration object:

KeyTypeDescription
views_nodestring[]Node view machine names to filter
views_termstring[]Term view machine names to filter
views_userstring[]User view machine names to filter
pattern_nodestring[]MySQL LIKE patterns for node titles
pattern_termstring[]MySQL LIKE patterns for term names
pattern_userstring[]MySQL LIKE patterns for user emails
list_termboolIf true, filters the taxonomy term overview page with the term patterns. If false, leaves that page unfiltered

By default, Testmode filters the content and user_admin_people views, matches node titles and term names against [TEST% and user emails against %example%, and filters the term overview page.

Vortex adds testmode to config_exclude_modules in settings.testmode.php, so the module and its settings stay out of the exported configuration. Configuration import therefore never enables it, which is why scripts/provision-10-enable-dev-modules.sh installs it alongside the other development modules, in the local, ci, dev, and stage environments. It's also a declared dependency of the ys_demo module, so installing the demo module brings it in as well.

Registering a view programmatically​

The Testmode singleton reads and writes that configuration. The settings stay out of the exported configuration, so register a view from a deploy hook in your module's MODULE.deploy.php file, as ys_demo does in ys_demo.deploy.php:

use Drupal\testmode\Testmode;

function ys_demo_deploy_configure_testmode(): string {
$testmode = Testmode::getInstance();

$views = $testmode->getNodeViews();
if (!in_array('ys_demo_pages', $views)) {
$views[] = 'ys_demo_pages';
$testmode->setNodeViews($views);
}

return 'Configured testmode to filter the pages view.';
}

The singleton has a getter and a setter for every key in the configuration table:

KeyGetterSetter
views_nodegetNodeViews()setNodeViews()
views_termgetTermViews()setTermViews()
views_usergetUserViews()setUserViews()
pattern_nodegetNodePatterns()setNodePatterns()
pattern_termgetTermPatterns()setTermPatterns()
pattern_usergetUserPatterns()setUserPatterns()
list_termgetListTerm()setTermsList()

The view and pattern setters accept an array or a newline-separated string. The list_term setter takes a boolean, and its name doesn't mirror the getter's: to stop filtering the term overview page, call setTermsList(FALSE). On the settings page, the same switch is the Include Taxonomy Terms Overview checkbox.

To drive the mode itself, the singleton has the following methods:

  • enableTestMode() turns test mode on.
  • disableTestMode() turns test mode off.
  • toggleTestMode() turns test mode on when passed TRUE, and off when passed FALSE.
  • isTestMode() returns TRUE while test mode is on.

Behat integration​

The @testmode tag turns test mode on for a single scenario and off again when it ends. It comes from TestmodeTrait in behat-steps, which the DrupalContext class that FeatureContext extends already includes, so the tag works without extra wiring. A tagged scenario fails straight away if the testmode module isn't enabled:

@testmode
Scenario: Pages view shows only test content when test mode is enabled
Given the following page content exists:
| title | status | moderation_state |
| [TEST] First test page | 1 | published |
| [TEST] Second test page | 1 | published |
When I go to "/pages"
Then I should see "[TEST] First test page"
And I should see "[TEST] Second test page"
And I should not see "Demo page"

The [TEST] prefix in content titles matches the default [TEST% pattern configured in Testmode. Only matching content appears in registered views, so the generated Demo page nodes stay out of the assertions.

To run the suite, or only this feature with ahoy test-bdd tests/behat/features/pages.feature, see Behat.

Example in Vortex​

The ys_demo module puts these pieces together:

  • It ships a pages view at /pages.
  • It registers the view with Testmode in the ys_demo_deploy_configure_testmode deploy hook.
  • It's covered by the pages.feature Behat feature in tests/behat/features, which demonstrates the @testmode tag against the generated content it filters out.