Our last blog post on Behavior Driven Development (BDD) explained how it is really a logical extension of Test Driven Development (TDD) with some important distinctions. One of those distinctions is the presence of ubiquitous language. This post will explain what ubiquitous language is and how it creates efficiencies across a multitude of areas including:
- Assisting in a better common understanding of acceptance criteria for requirements
- Creating a linear path to executable specifications
- Reducing overhead of excessive technical and end-user documentation
The point of using ubiquitous language is to “speak a common language”. All members of the team from Business Analysts to Developers to QA personnel and everyone else can easily understand exactly what the business is asking for. There is no ambiguity because potentially confusing terminology from the business, technical or industry vernacular is eliminated. Let’s start at the beginning with the requirements. For example you should NOT see something like “volume-based dynamic points system”. Instead you should see commonly understood language that specifies a desired behavior. For example, you might see requirements like this: “Customers who fly more than (10,000 miles per month) will automatically receive a 10% bonus in points”. That is about as clear as you can be!
So, how does that play out in practice you might ask? The requirements owner implements this in the form of a scenario. Scenarios can be thought of as a relative of a user story. The format is different and it is a higher level of abstraction but a scenario helps drive understanding like a user story. The following is an example1:
Provide frequent flyers with points based on flight mileage
Earning standard points from an economy flight
Given the flying distance between Sydney and Melbourne is 878 km
And I am a standard Frequent Flyer member
When I fly from Sydney to Melbourne
Then I should earn 439 points
The ubiquitous language and the structured format ensure you are building the right software because it is so intensely focused on driving the desired behavior. This format also leads directly to the second bullet point: creating a linear path to executable specifications. In addition to providing a common understanding for the purposes of requirements, scenarios have another purpose. Each scenario is comprised of logical steps. There is BDD software that will convert each of those individual steps into step definitions2, which in turn can be used to generate software for the product AND an automated test. On its face, this can seem like a brute force method to get to automated testing, but it is actually more elegant than that. The BDD software also allows you to create parameterized data so that there need NOT be a separate scenario for every closely related activity. The ability to add that level of abstraction makes BDD even more powerful because it opens the door for using tabular data to fully exercise the scenario during automated testing.
Once you have moved through BDD to this point, the final bullet point should become more evident: reducing the overhead of excessive technical and end-user documentation. The requirements are written using ubiquitous language. Step definitions are based on that same ubiquitous language so you don’t need a “Developer-to-English” dictionary to understand the code or the behavior being tested. The steps and step definitions themselves become the documentation. That’s because any unit tests written and/or integration tests written describe what the application is expected to do (aka system behavior) and the code being tested directly proves that the application is actually accomplishing the desired behavior. It creates a very neat, and useful feedback mechanism. Good development practices should ensure the unit/integration tests are reliable and easy to maintain/update. If that is true, then so is your documentation!
By now the value of BDD should be evident but there are some things you should consider before deciding to try it. Like any new endeavor, there are costs to entry. There is an underlying presumption that you know the problem domain thoroughly enough that you can distill the desired behaviors into language that is understandable by all team members. On its face this seems easy, but to be able to describe something in its simplest terms, requires the deepest understanding. You must also understand your team’s tolerance for change. Early attempts could be difficult and not yield much return compared to the effort expended. Is your team configured to deal with those circumstances?
It should be understood that BDD is not a cookie-cutter solution either. How it is implemented will depend heavily on the complexity of the problem you are solving as well as the business climate of your company and the contracts associated with the software under construction. Knowing that, it only makes sense to try BDD on a smaller scale to start. Are there starter or small scale projects that can be used for a pilot? Also understand that any BDD pilot will also require more energy to be successful because in order to mature, early attempts need lots of transparency and opportunities to inspect and adapt.
Now that we all have a basic understanding of BDD and the implications of adopting it, our next blog will take a look at the key points where BDD software automates information based on the scenarios to assist in developing the right software.
Authored by members of Cardinal's Agile Advisory Services, this post was written by Juan Flores, with contributions from Dave Wanner.
Example from “BDD in Action” by John Ferguson Smart
“The Cucumber for Java Book—Behavior-Driven Development for Testers and Developers” by Rose/Wynne/ HellesØy