Most of my work uses the Drupal framework, and I've given talks and workshops on automated testing and building custom Drupal modules with test-driven development. Today, I wanted to see how quickly I could get a working test suite on a new Drupal project.
I ran mkdir -p web/modules/custom/example/tests/src/Functional to create the directory structure that I needed, and then touch web/modules/custom/example/tests/src/Functional/ExampleTest.php to create a new test file and populated it with some initial code:
<?php
namespace Drupal\Tests\example\Functional;
use Drupal\Tests\BrowserTestBase;
use Symfony\Component\HttpFoundation\Response;
class ExampleTest extends BrowserTestBase {
protected $defaultTheme = 'stark';
}
For the simplest test, I decided to test some existing Drupal core functionality - that an anonymous user can view the front page:
/** @test */
public function the_front_page_loads_for_anonymous_users() {
$this->drupalGet('<front>');
$this->assertSession()->statusCodeEquals(Response::HTTP_OK);
}
To execute the test, I ran SIMPLETEST_DB=sqlite://localhost//dev/shm/test.sqlite SIMPLETEST_BASE_URL=http://web phpunit -c web/core web/modules/custom. The environment variables could be added to a phpunit.xml.dist file but I decided to add them to the command and use Drupal core's PHPUnit configuration file.
As this is existing functionalty, the test passes. I can change either the path or the response code to ensure it also fails when expected.
With the first test working, it's easy to add more for other functionality, such as whether different users should be able to access administration pages:
/** @test */
public function the_admin_page_is_not_accessible_to_anonymous_users() {
$this->drupalGet('admin');
$this->assertSession()->statusCodeEquals(Response::HTTP_FORBIDDEN);
}
/** @test */
public function the_admin_page_is_accessible_by_admin_users() {
$adminUser = $this->createUser([
'access administration pages',
]);
$this->drupalLogin($adminUser);
$this->drupalGet('admin');
$this->assertSession()->statusCodeEquals(Response::HTTP_OK);
}
Hopefully, this shows how quickly you can get tests running for a Drupal module. If you'd like to see more, the slides and video recording of my Test-Driven Drupal talk are online.
- Oliver
Was this interesting?
About me
I'm an Acquia-certified Drupal Triple Expert with 17 years of experience, an open-source software maintainer and Drupal core contributor, public speaker, live streamer, and host of the Beyond Blocks podcast.