fromAugust 2015
Column:

Testing, Testing... One... Two...Three

Moving Drupal 8 Forward
0

PhotoWriting tests for a project is a terrific way to learn about its underlying code. In the case of Drupal 8, nearly all the code is a complete overhaul from Drupal 7. For folks familiar with the inner workings of Drupal 7, writing PHPUnit tests for a given part of the codebase is a perfect way to understand what has changed.

As of June 2015, there are 566 active issues in the Drupal 8.0.x queue tagged with Needs tests. There’s lots of room for contribution for folks who can write a test. Since this column is dedicated to testing, let's look at the benefits of pushing Drupal 8 forward through test writing.

There are three different types of tests in Drupal 8:

  • Unit tests (PHPUnit) are used to test that the individual classes function as expected in relative isolation.
  • Integration tests (KernelTestBase) expand from this concept, but still only pull in code needed to test.
  • Functional tests (WebTestBase and BrowserTestBase) bring everything together, perform a full site install, and then assert the expected behavior.

Note that since the functional tests perform a full site install, they are quite slow, and should only be used when integration or unit tests are insufficient.)

To get started, find an issue in the “Needs work” or “Needs review” state that already has a patch and is tagged “Needs tests.” If the issue already has tests, update the issue to remove that tag and move along, or review the issue, give feedback, and then move along.

When a patch that only contains the fix is found, the next step is to backward-engineer the bug. The test must fail without the patch – meaning it shows that this is a bug – and then, with the patch, the test must pass. This pattern makes it easy for overworked core committers to see that the problem has been demonstrated and fixed.

For folks writing their first test, the ideal issue will have clearly defined “steps to reproduce” in the issue summary. The test then is essentially an automated way of reproducing those.

Let's use Issue #2482857: Cannot delete a book parent as an example.
To reproduce:

  1. Enable the Book module.
  2. Add a top-level book node.
  3. Add one or more child book nodes.
  4. Attempt to delete the parent node, note the exception.
  5. Try again and it succeeds.
  6. Visit one of the child nodes and note the fatal error.

The bug can be verified by manually performing those steps, but our test will ensure the fix doesn't regress later. Since this is testing the book module, tests will be found in core/modules/book/src/Tests or in core/modules/book/tests for unit tests. This test will be functional since it cannot be easily reproduced by a unit or integration test.

BookTest looks like a good starting point; it already enables the book module.

  /**
   * Modules to install.
   *
   * @var array
   */
  public static $modules = array('book', 'block', 'node_access_test');

Even better, it already has a helper function to build out a book with child nodes, BookTest::createBook(). The test also already includes one to test book deletion: BookTest::testBookDelete(). This means steps 1-3 above are essentially completed, so we just need to do 4-6:

     // Tests directly deleting a book parent.
     $nodes = $this->createBook();
     $this->drupalLogin($this->adminUser);
     $this->drupalGet('node/' . $this->book->id() . '/delete');
     $this->assertRaw(t('%title is part of a book outline, and has associated child pages. If you proceed with deletion, the child pages will be relocated automatically.', ['%title' => $this->book->label()]));
     // Delete parent, and visit a child page.
     $this->drupalPostForm('node/' . $this->book->id() . '/delete', [], t('Delete'));
     $this->drupalGet('node/' . $nodes[0]->id());
     $this->assertResponse(200);
     $this->assertText($nodes[0]->label());

The drupalGet and drupalPostForm methods are responsible for actually sending GET and POST requests to the test installation of Drupal, so we're really just clicking around the site here to achieve the steps to reproduce from above.

Once you have a failing test that illustrates the issue, this is posted as a test-only patch, meaning it is expected to fail. It is then combined with the fix for a patch that will pass. If you file an issue – or come across one without a patch – making the test patch to show the failure will greatly help moving the issue along since the person that eventually fixes it won't have to write that test, and it eliminates the need for manual testing as the patch is being written.

Whether you're just looking to learn more about the underlying code of Drupal 8, or want to really help push it out the door, writing tests is a great way to do both!

In future columns, I plan to dive deeper into the three test types mentioned above, as there is much to discover within.

Image: "Equilibrium 8_8_8" by Felipe Gabaldón is licensed under CC BY 2.0

Advertisement

From our blog

Entity Storage, the Drupal 8 Way

In Drupal 7 the Field API introduced the concept of swappable field storage.

The Drupal 6 to 8 Upgrade Challenge - Part 2

Having concluded the readiness assessment, we turn next to migrating the content and configuration. In reality, there’s little chance that we would migrate anything but the blogs from our old site. For the sake of giving Migrate in Core a workout with real conditions, however, we’re going to upgrade with core’s Migrate Drupal module rather than rebuilding.

The Drupal 6 to 8 Upgrade Challenge - Part 1

Nathaniel Catchpole , the Drupal 8 release maintainer and Tag1 Senior Performance Engineer, suggested that Drupal shops everywhere could support the

DrupalCon Austin

The entertainment industry is not for the faint of heart.

Drupal Watchdog Joins the Linux New Media Family
Drupal Watchdog 6.01 is the first issue published by Linux New Media.

Drupal Watchdog 6.01 is the first issue published by Linux New Media. Come see the Drupal Watchdog team at DrupalCon 2016!

Drupal Watchdog was founded in 2011 by Tag1 Consulting as a resource for the Drupal community to share news and information. Now in its sixth year, Drupal Watchdog is ready to expand to meet the needs of this growing community.

Drupal Watchdog will now be published by Linux New Media, aptly described as the Pulse of Open Source.

Welcome to DrupalCon Barcelona - The Director's Cut

For all you schedule-challenged CEOs – and ADHD coders – this Abbreviated Official Director’s Cut is just what the doctor ordered.

Welcome to DrupalCon - The Barcelona Edition

Did we have fun in Barcelona?
OMG, yes!

Did we eat all the tapas on the menu and wash them down with pitchers of sangria?
Yes indeed!

Recursive Closures and How to Get Rid of Them

This came up while manipulating taxonomy children and their children recursively, so it’s as not far from Drupal as you’d think.