Fizz Buzz

Understanding the laws and cycles of TDD

The FizzBuzz kata is one of the easiest kata to start practicing TDD. It poses a very simple and well-defined problem, so, in a first phase it’s very easy to solve it completely in a session of one or two hours. But, its requirements can also be expanded. Setting the requisite that the size of the list should be configurable, that new rules can be added, etc., should bump up the difficulty a bit and lead us to achieve more complex developments.

In this case, being our first kata, we’ll follow the simplest version.

History

According to Coding Dojo, the authorship of the kata is unknown1, but it’s commontly considered that it was introduced to society by Michael Feathers and Emily Bache in 2008, in the framework of the Agile2008 conference.

Problem statement

FizzBuzz is a game related to learning division in which a group of students take turns to count incrementally, saying a number each one, replacing any number divisible by three with the word “Fizz”, and any number divisible by five with the word “Buzz”. If the number is divisible by both three and five, then they say “FizzBuzz”.

So, our objective shall be to write a program that prints the numbers from 1 to 100 in such a way that:

  • if the number is divisible by 3 it returns Fizz.
  • if the number is divisible by 5 it returns Buzz.
  • if the number is divisible by 3 and 5 it returns FizzBuzz.

Hints to solve it

The FizzBuzz kata is going to help us understard and start applying the Red-Green-Refactor cycle and the Three laws of TDD.

The first thing we should do is to consider the problem and get a general idea about how we’re going to solve it. TDD is a strategy that helps us avoid the necessity of having to make a detailed analysis and an exhaustive design prior to the solution, but that doesn’t mean that we shouldn’t first understand the problem and consider how we’re going to tackle it.

This is also necessary to avoid getting carried away by the literal statement of the kata, which can lead us to dead ends.

The first thing we’re going to do, once we have that general idea on how to approach the objective, is to apply the first law and write a test that fails.

This test should define the first behavior that we need to implement.

Writing a test that fails means, at this time, writing a test that won’t work because there isn’t any code to run, a fact that will be pointed out to us by the error messages. Even though you might find it absurd, you must try to run the test and confirm that it doesn’t pass. It’s the test error messages that will tell you what to do next.

To get the test to fail we have to apply the second law, which says that we can’t write more tests than necessary to fail. The smallest possible test should force us to define the class by instantiating it, and little more.

Last, to make the test pass, we’ll apply the third law, which says that we mustn’t write any more production code than necessary to pass the test. That is: define the class, the method that we’re going to exercise (if applicable), and make it return some response that will finally make the test pass.

The two first steps of this stage are pretty obvious, but the third one, not so much.

With the first two steps we try to make the test fail for the right reasons. That is, first it fails because we haven’t written the class, so we define it. Then, it will fail because the method that we’re calling is missing, so we define it as well. Finally, it will fail because it doesn’t return the response that we expect, which is what we’re testing in itself.

And what response should we be returning? Well, no more no less than the one that the test expects.

Once we have a first test and a first piece of production code that makes it pass, we’ll ask ourselves this question: what will be the next behavior that I should implement?