Problem & Requirements

This is a worked example showing how to use TDD to write some code to solve a problem

This will use the classic 'Fizz Buzz' as the problem domain. The requirements are as follows;

  • If number divisible by 3 print Fizz
  • If number divisible by 5 print Buzz
  • If number divisible by 3 and 5 print FizzBuzz
  • All other cases, print the number
  • Example: 0 -> 0, 1 -> 1, 2 -> 2, 3 -> Fizz, 4 -> 4, 5 -> Fizz Buzz

Step 1 - Create a list of test cases

Start by thinking through the requirements and creating a list of test conditions. In this case its quite clear, but thinking like a Software Engineer, we can add a couple of additional use cases that our code needs to handle, but are not necessarily explicit requirements (e.g. error handling or null checks).
  • Do we accept negative numbers?
  • Do we accept integers or decimals?
Requirements capture is another ball game, but since we have asked the questions, then we shall say no on both counts.

Even in this simple example I don't want to mix presentation and logic layers, so we will aim to produce code to return the desired results, this can then be incorporated easily into any presentation layer (e.g print to console).

Test List

  • When a number is divisible by 3 return Fizz
  • When a number is divisible by 5 return Buzz
  • When a number is divisible by 3 & 5 return FizzBuzz
  • All other numbers return that number
  • Only accept whole integers in the range 0 to Integer.MAX
Next steps will involve writing unit test cases for each item on the list.
The work is complete when all requirements are met.

Comments

One approach I have seen many times is to take the requirements too literally, resulting in a main class which simply prints out the result. This is often done when tests are not written.
The issue here is that the code is basically untestable and not re-usable. By adopting a test first approach, the design is much cleaner, creating a fully tested re-usable class. We will explore this later in the tutorial.