Which D8 test is right for me?

Short history of Tests in Drupal

In Drupal 7 it was fairly straight forward what kind of a test you should write, especially for core. It would basically be a simpletest. If you wrote in contrib, you might write a few Behat or PHPUnit tests for your module, but you would either run these tests locally of on some remote testing server such as Jenkins or Travis.

While this was quite good for doing webtests along the lines of ‘create user’, ‘log in’, ‘go to page x’, ‘click on button y’, it was also pretty slow. Every patch on the issue queue could be delayed as much as 3 hours while all the tests ran and during sprint weeks we end up with huge queues of patches waiting to be tested.

Drupal 8 has really stepped up its game. In 2013 it separated our testing into two categories. one for web tests that require a complete or partial Drupal environment - Simpletests, and another for everything else - PHPUnit :) PHPUnit Change Notice

It didn’t take long for there to be several different subclasses for PHPUnit tests in Drupal:
Unit Tests
Kernel Tests
Functional Tests

What now?

So now the question is, “Which test should I be writing”. Here is a quick explanation of the different Test Base classes.

Drupal Test Structure

- TestCase (PHPUnit_Framework_TestCase)
  - \Drupal\KernelTests\KernelTestBase
  - \Drupal\simpletest\BrowserTestBase
  - \Drupal\Tests\UnitTestCase
- \Drupal\simpletest\TestBase
  - \Drupal\simpletest\KernelTestBase
  - \Drupal\simpletest\WebTestBase
    - \Drupal\simpletest\InstallerTestBase

TestCase and TestBase should never be extended directly. They are just structure that the remaining tests extend.

UnitTestCase is what you want if you don’t care about bootstrapping Drupal. All you want to do is test Class methods and make sure that they behave expectedly. Eg. If your method required the first argument to be a string and you pass it an array you get an exception, etc.

Next up we have KernelTestBase, WebTestBase and BrowserTestBase. These all do something towards setting up a Drupal Environment and allowing you to test your code in the wild. KernelTestBase is the simplest as it bootstraps Drupal and sets up a Database, etc. but it doesn’t explicitly install any modules, and so is similar to the environment in the early installer. Any modules that you require are loaded in setUp() and you can perform schema installation as required.

Notice: there are two KernelTestBase classes. \Drupal\simpletest\KernelTestBase has been deprecated for \Drupal\KernelTests\KernelTestBase as part of Drupals continuing battle to modernise its testing and has moved from simpletest to PHPUnit. KernelTestBase Change Notice

Then we get to WebTestBase and BrowserTestBase. They do basically the same thing, as they allow a full installation of Drupal and modules and are webtests so you test the UI through a browser. The general rule of thumb is use WebTestBase. BrowserTestBase is the newest move to modernize testing as it is an attempt to move Browser Testing from simpletest to PHPUnit and Mink BrowserTestBase Change Notice. So if you fancy it, you can give the new framework a go, but it is still work in progress and not going to be used extensively in core until 8.1.x.

And finally there is InstallerTestBase which is useful testing the installation of Drupal based on changes in configuration.