Lesson Tuesday

One of the most difficult challenges facing us as developers is taking a problem we want to solve or a concept we want to realize and turning it into a set of specific programming tasks.

A common process to do this is called Behavior-Driven Development (or BDD) and is used by developers across coding languages. In BDD, rather than thinking about the code first, the focus begins on the behaviors that we want to see in our final application. We identify what the program should do before determining how to make it do it.

To practice this, we'll imagine that we have been hired by a person born on February 29th. She would like to determine if any given year is a leap year (meaning it's a birthday year for her!). Here's a finished example of what she'd like: Leap year detector.

Before we think about the programmatic elements, what should a leap year program do? At its most basic, it will need to be able to take a year from the user and answer true or false to the question: is this year a leap year? Our program will only be able to provide an answer once it successfully evaluates what the user provides as a year. Let's think of all of the possibilities we might get from a user and what the correct response should be for them.

Specifications

Timeanddate.com offers us the 3 criteria that must be considered to determine if a year is a leap year:

  • The year is evenly divisible by 4;
  • If the year can be evenly divided by 100, it is NOT a leap year, unless;
  • The year is also evenly divisible by 400. Then it is a leap year.

Therefore, each time a user offers a year to evaluate, we will ultimately need to test the value against each of the leap year rules.

In BDD, our next step is to generate examples of these rules one-by-one. These examples are also known as specifications or specs. We can create a table that helps us sort out the details of the specifications for each rule using the following pieces of information:

  • the behavior that we'll need to write code to handle
  • a sample of input that would demonstrate the behavior
  • the expected output we'd get when the code is working correctly

Leap Year Input-Output Grid

Although there are many other considerations for our final application (display, user interaction, form building, what if someone enters a letter?, etc), we will not worry about those until we have the core functionality in place. If we think of any additional functionality we need, we can add behaviors to our specification list as we go. When you code using BDD, it is good to get into the habit of making a note of all behaviors as you think of them, but staying focused on one task at a time.

Let's look at another example of specs organized on a table showing behavior, input and output:

Title Case

In this example, we want to build an application that will take a user's string of words and convert them to title case - capitalizing letters like we'd find in a book title. There are a few more rules for creating title cased words from strings than Leap Year. Let's brainstorm the first several:

BDD Table for Title Case

As we did with the leap year application, we choose the simplest first - one word gets capitalized - beowulf becomes Beowulf and go to the most complex. And as always, we may think of additional behaviors along the way: what if a user enters nothing? what about iPod or McDuff? Remember, let your brain keep brainstorming by adding new behaviors to your list but always stay focused on one specification at a time.

Terminology


  • Behavior-Driven Development: Used by developers across coding languages. In BDD, rather than thinking about the code first, the focus begins on the behaviors that we want to see in our final application. We identify what the program should do before determining how to make it do it.

  • Specifications or Specs: Examples of small, isolated behaviors a program should demonstrate, including input and output examples.

    • the behavior that we'll need to write code to handle
    • a sample of input that would demonstrate the behavior
    • the expected output we'd get when the code is working correctly

Example


Leap Year Input-Output Grid