oliverdavies.uk/source/_pages/atdc/2.md

4.4 KiB

title permalink
Lesson 2 - Diving Deeper /atdc/2-diving-deeper

{% block head_meta %}

{% endblock %}

{% block content %} At the end of the last lesson, we had a working test suite, with tests ensuring the correct response codes were returned from Drupal's front and administration pages.

So, how do we move on from here?

Testing as an authenticated user

In the current tests, we're testing the responses as an anonymous user.

So, how do we test as an authenticated user?

For example, how do we test the administration pages to see if they work for a user who's logged in?

Let's start with a new test:

public function testAdminPageLoggedIn(): void {
  $this->drupalGet('/admin');

  $assert = $this->assertSession();
  $assert->statusCodeEquals(Response::HTTP_OK);
}

This is the same test as before, only with a different expected status code. This time, we want a 200 status code, but as we're still anonymous, this test will fail.

Creating a user

Before we move on, an important thing to note is that these tests don't test against the data in your database.

A fresh installation from a testing profile is done for each test method, meaning each test is run against an empty Drupal site. This is why you didn't need to install Drupal in the first lesson and why it only needed to be running.

So, if you have existing users in your database, they won't be there to use.

This prevents contamination between tests, but you need to create the required data and environment for each test.

This is commonly known as the Arrange step of the test.

To create a user, use $this->drupalCreateUser() and $this->drupalLogin() to log in as that user.

$user = $this->drupalCreateUser();

$this->drupalLogin($user);

Now, we're no longer anonymous, though this test will still fail. Not all authenticated users can access the administration area.

To do this, a user needs two specific permissions - access administration pages and administer site configuration.

As we're testing against a temporary Drupal installation, we don't have access to any custom roles, so we must add the permissions directly to the user instead of to a user role.

To do this, when creating the user, include an array of permissions to add to it:

$user = $this->createUser(permissions: [
  'access administration pages',
  'administer site configuration',
]);

For readability, I like to add permissions as a named parameter, but it's optional.

With the permissions added, run phpunit, and the new test should pass.

What about content?

The same as users, we need to create any content we need in each test.

Let's create a page and test we can view it.

Firstly, let's ensure the page is not found:

public function testContent(): void {
  $this->drupalGet('/node/1');
  $this->assertSession()->statusCodeEquals(Response::HTTP_NOT_FOUND);
}

Similar to $this->createUser(), there are similar methods to create content types and nodes.

Again, as there are no existing content or content types, we need to create them and add the follow-up assertions:

public function testContent(): void {
  // ...

  $this->createContentType(['type' =>'page']);
  $this->createNode(['type' => 'page']);

  $this->drupalGet('/node/1');
  $this->assertSession()->statusCodeEquals(Response::HTTP_OK);
}

Enabling additional modules

You're probably expecting the test to pass now, but you'll likely get an error like this:

Drupal\Core\Entity\Exception\NoCorrespondingEntityClassException: The Drupal\node\Entity\Node class does not correspond to an entity type.

To fix this, we need to tell Drupal to enable the node module within the test by adding this within the test class:

protected static $modules = ['node'];

If we need any additional modules, we can add those too.

Debugging

Here's a tip for today: if you're getting an unexpected status code or another error that you want to debug, you'll need to output the page content to see the error.

To do that, add this to your test, and it will output the page content:

var_dump($this->getSession()->getPage()->getContent());

Conclusion

In this lesson, you expanded your test suite to test as an authenticated user, and that content exists by creating a content type and node.

Tomorrow, we'll start building a new module from scratch. {% endblock %}