The curious lifecycle of behaviour driven development scenarios

Behaviour Driven Development offers some unique benefits compared to document artefacts found in more traditional software development projects. One of the more useful benefits is that it's a shared document that lives, and provides value, throughout the life cycle of a software project.

Consider a long lived document like the one hinted at above, compared to a Business Requirements Specification, plus a Functional Specification, plus a Technical Specification, and then ultimately, a Test Suite which all essentially hand off from one to the other. A wholly unwanted side-effect of this is a broken telephone effect, where definite and non-negligible loss in the fidelity of requirements naturally unfolds. BDD essentially eliminates the need for these different documents, and offers a simpler way to collaborate and maintain requirements knowledge over a project's lifetime.

This article aims to outline some of our experience in what happens when building out cucumber specifications with clients, and how to spot and remedy some of the pitfalls that may occur.

The egg stage

This stage of the development process is filled with promise. The whole team envisions all the possibilities that could emerge from this tiny seed.

For this phase, analysts should work primarily with business stakeholders (although it's encouraged that developers and testers are present too) to gather high level features, and turn as many of those features as feasible into User Stories, or preferably Job Stories. This serves as the basis for why a feature, as we like to say, deserves to live.

What you'll typically find during this phase is that scenarios built here will be of the declarative ilk. A common phenomenon here will be that they might be too declarative to the point of being nearly unusable. This is absolutely fine and normal. To counteract this, it is extremely important that the essence feature story is rock-solid. Feel free to mitigate some of the vagueness by putting some rough wireframes together.

    Feature: Place an order for new shoes.
        When I've found the perfect pair of shoes and it's a few days until the party
        I want to pay for them and ship them with priority
        So I can get them in time and not have to wear my old pair.

        Scenario: Pay for shoes
            Given I have found my pair of shoes
              And I have entered my credit card details
             When I click 'Buy'
             Then I should have a payment receipt in my inbox.

The caterpillar stage

We're now at the point where we have something to work with, it may be a little hairy, a little unwieldy, and none too graceful, but it's a start, and the promise of something great can be seen.

Once the developers have enough to go on (what this exactly is serves as the basis for a whole other post), they can start developing based off a prioritised list of features and scenarios within those features. Developers will typically tweak the scenarios to be more inline with some of their scenario parsing tools, and this may mean an inching towards a more imperative style of scenario. Manage these changes via collaborative channels.

Once developers start closing off features according to the scenarios outlining behaviour, it's crucial that two things happen.

1) The analyst in charge ensures that features and scenarios are up to date, and there are more waiting for developers. 2) Testers get at the software that's ready for testing.

    Feature: Place an order for new shoes.
        When I've found the perfect pair of shoes and it's a few days until the party
        I want to pay for them and ship them with priority
        So I can get them in time and not have to wear my old pair.

        Background:
            Given I am logged in
              And my credit card details are saved to my account

        Scenario: Pay for shoes
            Given I have added 'Nike MAGs' to my basket
              And I have selected 'Expedited Shipping'
             When I click 'Buy'
             Then I should see a successful transaction message with a receipt number

The pupa stage

At this point in a scenario's lifecycle, things start to settle down and take real shape. Final forms are fleshed out, and by now we will have a real inkling of what lies ahead.

Any good tester worth their salt should actually be called a quality engineer. They'll look past the features and consider other aspects like user experience, usability, speed, load testing and security. BDD doesn't attempt to replace any of these toolsets, so make sure they're still covered.

Where a tester can add to the BDD cycle is by adding boundary testing, and fuzz testing to the suite. Whether or not this is kept in separate feature files to keep the so-called happy path clear, or whether an imperative or declarative style is used is entirely up to the convention of the delivery team. The only recommendation is that consistency is applied.

It's important to state is these features and scenarios are used manually (i.e they haven't been wired up to automation code yet), stay as imperative as you can.

    Feature: Place an order for new shoes.
        When I've found the perfect pair of shoes and it's a few days until the party
        I want to pay for them and ship them with priority
        So I can get them in time and not have to wear my old pair.

        Background:
            Given I am logged in
              And my credit card details are saved to my account

        Scenario: Pay for shoes
            Given I have added 'Nike MAGs' to my basket
              And I have selected 'Expedited Shipping'
             When I click 'Buy'
             Then I should see a successful transaction message with a receipt number

         Scenario:Item is out of stock
             Given I have added 'Glass Slippers' to my basket
              When I click 'Buy'
              Then I should see an out of stock message

The imago stage

By now, we should have a full set of features and scenarios that map 1:1 to delivered software. In order to keep our beautiful software alive, it's important that it continues to undergo micro-lifecycles within it's project. When a feature changes, is removed, or replaced, follow the same process and make sure everyone involved in the delivery is still included and collaborated with.

    Feature: Place an expedited order for new shoes.
        When I've found the perfect pair of shoes and it's a few days until the party
        I want to pay for them and ship them with priority
        So I can get them in time and not have to wear my old pair.

        Background:
            Given I am logged in
              And my credit card details are saved to my account
              And my default shipping preference is 'Expedited'

        Scenario: Pay for shoes
            Given I have added 'Nike MAGs' to my basket
             When I click 'Buy'
             Then I should see a successful transaction message with order and tracking numbers

Some BDD nuggets

  • Automate your test suite at the earliest opportunity, and get that automation into your CI platform.
  • Analysts need to walk a fine line between declarative and imperative features. When in doubt, ask yourself, "Would the stakeholder find these features too detailed?". If yes, and they must be imperative, put them in a feature file marked as not important for stakeholders, or at the very least, a separate section in a feature file clearly marked for testing only.
  • BDD features and scenarios are not a proxy for face-to-face collaboration.
  • Expect the BDD process to spark conversations about the software. Be ready to act on the feedback from those conversations.
  • Testers and analysts will need to have a basic understanding of the development teams revision control process in order to add to the content of scenarios and, as a bonus, should be able to spin up their own development environment to play with pre-prod versions of the software. There are plenty of GUI apps, and Devops toolsets to make this easier.
comments powered by Disqus