Traits for testing Drupal sites that have user content (versus unpopulated sites).

1.0.0-beta.1 2018-09-06 17:26 UTC


Build status project-stage-badge license-badge


Traits for testing Drupal sites that have user content (versus unpopulated sites).

Behat is great for facilitating conversations between business managers and developers. Those are useful conversations, but many organizations simply can't/wont converse via Gherkin. When you are on the hook for product quality and not conversations, this is a testing approach for you.


composer require 'weitzman/drupal-test-traits'

Authoring tests

Pick a test type:

  1. ExistingSiteBrowser. See ExampleTest.php. These tests can be small unit tests up to larger Functional tests (via Goutte).
  2. ExistingSiteSelenium2. See ExampleSelenium2DriverTest.php. These tests make use of any browser which can run in web driver mode(Chrome, FireFox or Edge) via Selenium, so are suited to testing Ajax and similar client side interactions. This browser setup can also be used to run Drupal 8 core JS testing using nightwatch. These tests run slower than ExistingSite.
  3. ExistingSiteWebDriver. See ExampleWebDriverTest.php. These tests make use of a headless Chrome browser, so are suited to testing Ajax and similar client side interactions. These tests run slower than ExistingSite.

Extend the base class that corresponds to your pick above: ExistingSiteBase.php, ExistingSiteWebDriverTestBase.php, or ExistingSiteSelenium2DriverTestBase.php. You may extend it directly from your test class or create a base class for your project that extends one of these.

To choose between ExistingSiteWebDriverTestBase.php, or ExistingSiteSelenium2DriverTestBase.php for JS (Ajax and similar client side interactions) testing read testing Drupal with WebDriver browser mode vs Headless browser mode.

Running tests

  • You must specify the URL to your site as an environment variable: DTT_BASE_URL=http://example.com. For ExistingSiteJavascript also specify DTT_MINK_DRIVER_ARGS=["firefox", null, "http://selenium:9222/wd/hub"] or DTT_API_URL=http://localhost:9222. Here are three ways to do that:
    • Specify in a phpunit.xml. See example.
    • Enter that line into a .env file. These files are supported by drupal-project and Docker.
    • Specify environment variables at runtime: DTT_BASE_URL=;DTT_API_URL=http://localhost:9222 vendor/bin/phpunit ...
  • Add --bootstrap option like so: --bootstrap=vendor/weitzman/drupal-test-traits/src/bootstrap.php
  • Depending on your setup, you may wish to run phpunit as the web server user su -s /bin/bash www-data -c "vendor/bin/phpunit ..."

Debugging tests

  • For ExistingSite, all HTML requests can be logged:
    • Define the environment variable BROWSERTEST_OUTPUT_DIRECTORY. See .env.example or docs/phpunit.xml for guidance.
    • Add --printer '\\Drupal\\Tests\\Listeners\\HtmlOutputPrinter' to the phpunit call. Alternatively specify this in a phpunit.xml.
  • For ExistingSiteSelenium2 or ExistingSiteWebDriver , use file_put_contents('public://screenshot.jpg', $this->getSession()->getScreenshot()); to take screenshot of the current page.
  • To check the current HTML of the page use file_put_contents('public://' . drupal_basename($session->getCurrentUrl()) . '.html', $this->getCurrentPageContent());

Bootstrap options

To allow use of ExistingSite and ExistingSiteJavascript autoloading to be work alongside core's (Unit, Kernel, etc), this project's bootstrap.php should be used:

vendor/bin/phpunit --bootstrap=vendor/weitzman/drupal-test-traits/src/bootstrap.php

Alternatively, specify this in a custom phpunit.xml file (See example).

If you have your own bootstrap.php file, refer to this project's version, and add the ExistingSite and ExistingSiteJavascript namespaces logic to your own.

Available traits

  • DrupalTrait
    Bootstraps Drupal so that its API's are available. Also offers an entity cleanup API so databases are kept relatively free of testing content.

  • GoutteTrait
    Makes Goutte available for browser control, and offers a few helper methods.

  • Selenium2DriverTrait
    Make Selenium2Driver available for browser control with Selenium. Suitable for functional javascript testing.

  • WebDriverTrait
    Make ChromeDriver available for browser control without the overhead of Selenium. Suitable for functional javascript testing.

  • NodeCreationTrait
    Create nodes that are automatically deleted at end of test method.

  • TaxonomyCreationTrait Create terms and vocabularies that are deleted at the end of the test method.

  • UserCreationTrait Create users and roles that are deleted at the end of the test method.

  • MailCollectionTrait
    Enables the collection of emails during tests. Assertions can be made against contents of these as core's AssertMailTrait is included.


Contributions to the this project are welcome! Please file issues and pull requests. All pull requests are automatically tested via GitLab CI.

See docker-compose.yml for a handy development environment.

See the #testing channel on Drupal Slack for discussion about this project.