Drupal Dev Days Leuven 25

BDD and Behat. What, why, and how?

Dropsolid logo

BDD and Behat. What, why, and how?

bit.ly/leuven2025ddd

Slides are hosted on github, press 's' if you want to read speaker notes too.


About myself

Valery "valthebald" Lourie

https://dropsolid.ai

Agenda

  • What is BDD?
  • Why BDD matters
  • Behat implementation
  • Practical examples

What is BDD?

  • Behavior-Driven Development
  • Extension of Test-Driven Development (TDD)
  • Focus on business value and user behavior
  • Uses ubiquitous language that everyone understands

My name is Valery, and I write terrible code

Valery 'valthebald' Lourie

Milestones

  • Prehistoric (before 1950s)
  • First high level languages
  • Object-oriented programming (1960s-1980s)
  • World Wide Web (1982)
  • Visual programming and low code (2000s)

AI will make it even easier

Feverishly typing robot

How BDD can help here?

  • Use common language
  • Driven by examples
  • Tests as a living documentation
  • Focus on what and why

Introducing Behat

  • PHP framework for BDD
  • Uses Gherkin syntax
  • Integration with Mink for web testing
  • Extensible with contexts

Gherkin Example


Feature: User authentication
  In order to protect accounts
  As a website administrator
  I need to ensure users can login securely

  Scenario: Successful login
    Given I am on the login page
    When I fill in "username" with "admin"
    And I fill in "password" with "password"
    And I press "Log in"
    Then I should see "Welcome back"

Setting Up Behat


# Install Behat
composer require --dev behat/behat

# Initialize Behat
vendor/bin/behat --init

# Install Mink and extensions
composer require --dev behat/mink-extension
composer require --dev behat/mink-goutte-driver
composer require --dev behat/mink-selenium2-driver

Behat Configuration


# behat.yml
default:
  suites:
    default:
      contexts:
        - FeatureContext
        - Drupal\DrupalExtension\Context\DrupalContext
        - Drupal\DrupalExtension\Context\MinkContext
  extensions:
    Behat\MinkExtension:
      goutte: ~
      selenium2: ~
      base_url: http://example.com
    Drupal\DrupalExtension:
      blackbox: ~

Creating Contexts


<?php
use Behat\Behat\Context\Context;
use Behat\Mink\Exception\ExpectationException;

class FeatureContext implements Context
{
    /**
     * @Then I should see the heading :heading
     */
    public function iShouldSeeTheHeading($heading) {
        $page = $this->getSession()->getPage();
        $found = $page->findAll('css', 'h1, h2, h3, h4, h5, h6');
        
        foreach ($found as $element) {
            if ($element->getText() === $heading) {
                return;
            }
        }
        
        throw new ExpectationException(
            "The heading '$heading' was not found",
            $this->getSession()->getDriver()
        );
    }
}

BDD Workflow

  1. Write feature description and scenarios
  2. Run Behat to generate step definitions
  3. Implement step definitions
  4. Run tests (they should fail initially)
  5. Implement functionality to make tests pass
  6. Refactor and repeat

Drupal-specific Testing


Feature: Content management
  As a content editor
  I need to be able to create and edit content
  So that I can manage the website effectively

  Scenario: Create an article
    Given I am logged in as a user with the "editor" role
    When I go to "node/add/article"
    And I fill in "Title" with "Test Article"
    And I fill in "Body" with "This is a test article"
    And I press "Save"
    Then I should see "Article Test Article has been created"

Advanced Behat Techniques

  • Scenario Outlines for data-driven tests
  • Tagging scenarios (@javascript, @api)
  • Background steps for common prerequisites
  • Custom step definitions for complex actions

Common Challenges

  • JavaScript-heavy applications
  • Test isolation and cleanup
  • Test data management
  • Flaky tests due to timing issues
  • Maintaining fixtures and environments

Best Practices

  • Write scenarios from user perspective
  • Keep scenarios focused and concise
  • Use domain-specific language
  • Ensure test isolation
  • Integrate with CI/CD pipeline

AI + Behat = Love?

Developing a feature in AI era

  • Describe a feature in a natural language
  • Generate "real" feature file
  • Generate missing step definitions if needed
  • Ask code generation tool to write the code
  • Manually check that the code works
  • Run the new feature (added to the testing set)

Resources

Questions?

bit.ly/leuven2025ddd