How to use BDD to increase project collaboration - with Drupal 8 and BLT

  • Matteo De Micheli

I first came in touch with Behaviour Driven Development (BDD) while working on a project with complex business requirements. Since then I’ve been a proponent of BDD as a technique to develop and test applications. In a typical project, clients, product owners and developers use it to ensure quality.

In contrast to Test Driven Development (TDD) it impacts not only development but also the specification of tasks, their testing and implementation. Since we don't want to reinvent the wheel, we will be using BLT (by Acquia) to easily set up Drupal 8 with BDD. It's fun, let’s check it out.

How does it work?

At the center, BDD is a human readable specification of a task focussing on behavior. This makes it possible for product owners and clients to guide the implementation and leave out unnecessary details. Let's describe a feature in Gherkin.

Scenario: User can see the logo on the homepage
  Given I am logged in as TestUser
  And I visit the homepage
  Then I should see the logo

This is an example of a specification that ensures that the logo is visible on the homepage. It covers the prerequisites (Given) and the implementation (Then) with the focus of what's important to the stakeholders. Writing well-thought-out specifications is helpful to pinpoint the requirements of the client. The result is a text in plain English that is understandable to both developers and stakeholders.

In my experience, it's very important to have the team commit to specifications as the primary way of solving tasks. It takes a bit of time to learn the Gherkin syntax. But the advantages are a shared understanding of the requirements and less unnecessary clarification.

Development setup

To set up a simple Drupal application with BDD we will use blt. Check out the following page for system requirements. Run following commands to set up a Drupal 8 project.

# Create blt drupal project with composer
composer create-project --no-interaction acquia/blt-project drupal-8-bdd-project
# Navigate into project folder
cd drupal-8-bdd-project/
# Start up vm
blt vm
# SSH into the vagrant machine
vagrant ssh
# Set up local drupal project
blt setup
# Set up (only on first call) and run behat
blt tests:behat

Check out local.drupal-8-bdd-project.com to see the Drupal 8 app 🎉.

Testing - the behat way

We will now use the example specification that we created before and implement it as a behaviour driven test. We need to slightly change the definition though to reuse code. Create a file called CorporateIdentity.feature at tests/behat/features/.

# tests/behat/features/CorporateIdentity.feature
Feature: Corporate identity
  In order to verify that users recognize the company
  As a user
  I should be able to see the website based on the corporate styleguide

  @api
  Scenario: User can see the logo on the homepage
    Given I am logged in as a user with the "authenticated user" role
    And I am on "/"
    Then I should see the logo

The feature title and the three lines beneath give context to what the feature is about. The @api annotation above the scenario definition is a magically defined driver in the behat configuration (tests/behat/behat.yml). By default it uses the DrupalDriver to bootstrap the Drupal application. The slightly adjusted scenario definition reuses the Drupal context code. Therefore we only need to implement the Then I should see the logo definition.

Inside tests/behat/features/bootstrap/Drupal/FeatureContext.php add the following method.

<?php

namespace Drupal;

...
  public function __construct() {

  }

  /**
   * Asserts that the logo is visible.
   *
   * @Then /^(?:|I )should see the logo$/
   *
   * @throws \Behat\Mink\Exception\ElementHtmlException
   */
  public function assertLogoIsVisible() {
    $this->assertSession()->elementAttributeContains(
      'css',
      '.site-branding__logo img',
      'src',
      'lightning.png'
    );
  }
}

The @Then annotation accepts a regex which evaluates what function has to be run. The code uses Mink to assert the image element and the src attribute containing the expected image. Run the following command to see the specification succesfully pass.

blt tests:behat

Conclusion

I used BDD in a few projects and it has been great to minimize unnecessary work and ensure that things work as expected. Seeing specifications pass successfully is also kinda fun and reassuring. What experiences did you have with BDD? Did they differ from mine? Looking forward to reading about it.


Qu’en pensez-vous?