Why I use BDD for unit testing

Use behaviour driven development (BDD) to do more than just acceptance testing.

This post makes the following assumptions

When I say BDD, I’m talking about Gherkin and SpecFlow

Gherkin is the syntax I use to express a system’s behaviour in a natural (universal) language. Here is an example of a calculator feature in Gherkin that I will use for the rest of this post.

Feature: Calculator
  In order to avoid silly mistakes
  As a math idiot
  I want to be told the sum of two numbers

@unit
Scenario: Add two numbers
  Given I have entered 50 into the calculator
  And I have entered 70 into the calculator
  When I press add
  Then the result should be 120 on the screen

As you can see, using Gherkin has many advantages.

  • Natural spoken language
  • A ubiquitous language that you can share with non-technical stakeholders
  • Define high-level behaviour (implementation agnostic)

How does this translate into unit tests?

SpecFlow is the tool I use to convert Gherkin into test stubs. It was made specifically for C# .NET and I use it together with xUnit.

When we generate the step definitions for the feature above using SpecFlow, we get the following.

[Binding]
public class CalculatorSteps
{
    [Given(@"I have entered (.*) into the calculator")]
    public void GivenIHaveEnteredIntoTheCalculator(int number)
    {
        ScenarioContext.Current.Pending();
    }

    [When(@"I press add")]
    public void WhenIPressAdd()
    {
        ScenarioContext.Current.Pending();
    }

    [Then(@"the result should be (.*) on the screen")]
    public void ThenTheResultShouldBeOnTheScreen(int result)
    {
        ScenarioContext.Current.Pending();
    }
}

By looking at the test stubs generated by SpecFlow without implementing the test body, can we tell what type of test this is?

  • Is this functional (end-to-end) testing?
  • Is this integration testing?
  • Is this unit testing?

The point being, it is none of the above. In my opinion, BDD (Gherkin and SpecFlow) doesn’t restrict (or care) how you use the steps. The steps describe how to verify the behaviour described by the feature. Not which components to test.

Given that BDD is agnostic to the test pyramid, we could very quickly generate a set of steps for each level of testing. Including unit tests.

Given a feature and a known set of inputs, when I perform an action, then I should expect a known set of outputs

Since I have started using BDD style unit testing, I have noticed the following benefits.

  • I describe my tests (scenarios) in a natural and ubiquitous language that I can share with non-technical stakeholders.
  • I can add and remove test cases (inputs and outputs) to my tests without modifying the code by using Gherkin’s scenario outline.
  • I can use the same set of behaviours to do multiple levels of testing. For example, I start with unit tests, then move on to API tests and then UI automation testing with the same feature scenario.
  • I can re-use (pragmatically) steps in a feature to test multiple scenarios without repeating code.
  • I can convert the same set of tests into a different language or technology stack without any modifications to the Gherkin syntax.

Share your thoughts and experiences with BDD and how you use it in your test regime.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s