At Nuvole we consider writing good tests as a fundamental part of development and, when it comes to testing a complex site, there is nothing better than extensive behavioral tests using Behat. The benefits of such a choice are quite obvious:
Tests are very easy to write.
Behat scenarios serve as a solid communication mean between business and developers.
As a site grows in complexity, however, the default step definitions provided by the excellent Behat Drupal Extension might not be specific enough and you will quickly find yourself adding custom step to your FeatureContext or creating custom Behat contexts, as advocated by all officialdocumentation.
This is all fine except that your boilerplate test code might soon start to grow into a non-reusable, non-tested bunch of code.
Nuvole's Behat Drupal Extension is built on the shoulders of the popular Behat Drupal Extension and it focuses on step re-usability and testability by allowing developers to:
Organize their code in services by providing a YAML service description file, pretty much like we all are used to do nowadays with Drupal 8.
Override default Drupal Behat Extension services with their own.
Benefit of many ready-to-use contexts that are provided by the extension out of the box.
Installation and setup
Install Nuvole's Behat Drupal Extension with Composer by running:
$ composer require nuvoleweb/drupal-behat
Setup the extension by following the Quick start section available on the original Behat Drupal Extension page, just use NuvoleWeb\Drupal\DrupalExtension instead of the native Drupal\DrupalExtension in your behat.yml as shown below:
All contexts extending \NuvoleWeb\Drupal\DrupalExtension\Context\RawDrupalContext and \NuvoleWeb\Drupal\DrupalExtension\Context\RawMinkContext are provided with direct access to the current Behat service container. Developers can also define their own services by adding a YAML description file to their project and setting the services: parameter to point to its current location (as shown above).
The service description file can describe both custom services and override already defined services. For example, given a tests/my_services.yml containing:
Say that, while working on your Drupal 7 project, you have defined a step that publishes a node given its content type and title and you want to use the same exact step on your Drupal 8 project, something like:
Given I publish the node of type "page" and title "My page title"
The problem here is that the actual API calls to load and save a node differs between Drupal 7 and Drupal 8.
The solution is to override the default Drupal core services specifying your own classes in your tests/my_services.yml: