How to run functional test in Drupal?

·

2 min read

Install packages

Here are the steps to start the test. Lets assume that your Drupal codebase has been already installed with the composer.

We need additional packages:

composer require --dev drupal/core-dev - install additional tools
composer require --dev phpunit/phpunit ^9 - add phpunit

If the other packages are needed, just install them.

If there is a problem with symfony/finder - just remove drush for the time of installation and install it afterwards.

Adjust settings

Now lets copy the default phpunit settings found inside web/core:

cp web/core/phpunit.xml.dist web/core/phpunit.xml - copy settings inside web/core

change the following lines in file:

<env name="SIMPLETEST_BASE_URL" value="http://localhost"/>
<env name="SIMPLETEST_DB" value="sqlite://localhost//dev/shm/test.sqlite"/>
<env name="BROWSERTEST_OUTPUT_DIRECTORY" value="/web/sites/simpletest/browser_output"/>

Note that the Drupal will prepare the skeleton page that won't touch your database, so you could use sqlite just for the testing purposes.

Knowing the browser output directory you can see the result of the tests by yourself !

Run the tests

Enter the container or use the php server and enter the web/core directory and from there - fire the tests ../../vendor/bin/phpunit ../modules/custom/XXXX

Pay attention to the namespace in the module! The test should be located in web/modules/custom/XXXX/tests/src/Functional/YourFunctionalityTest.php

Here's some basic test file for the reference:

<?php

namespace Drupal\ns_register\Functional;
use Drupal\Tests\BrowserTestBase;
use Symfony\Component\HttpFoundation\Response;


/**
 * Tests accept terms form.
 *
 * @group ns
 */
class AcceptTermsFormTest extends BrowserTestBase {
  protected $defaultTheme = 'myown_emulsify';
  protected static $modules = [
    'node',
    'views',
    'components',
    'emulsify_twig',
    'ns_register',
  ];

  /**
   * Tests that the home page loads with a 200 response.
   */
  public function testLoad(): void {
    $this->config('system.site')
      ->set('page.front', '/register/step1')
      ->save(TRUE);
    $this->drupalGet('<front>');
    $assert = $this->assertSession();
    $assert->statusCodeEquals(Response::HTTP_OK);
    $assert->pageTextContains('Before you register');
  }
}

The big source of inspiration

Struggling with understanding the way the tests work in Drupal - this repo helped me a lot.