This developer's chronicles

Web development using Scrum, C#, AngularJS and the like

Tag: unit test

Using Test Driven Development TDD to solve FizzBuzz

The first time I saw the FizzBuzz problem was when watching a Pluralsight video authored by Jesse Liberty quite a while ago and today as part of my TDD training at the FireBootCamp I get to solve it by using my new tool (TDD)

Defining the problem

Before we start, and for the ones who are not familiar with the FizzBuzz problem, the idea is to display integers from 1 to 100, but for multiples of three we’ll display the word ‘Fizz’ instead of the integer, for multiples of five we’ll output ‘Buzz’ instead of the integer and for multiples of 3 and 5 we’ll display FizzBuzz, an example of the output below:

1
2
Fizz
4
Buzz
Fizz
7

94
Buzz
Fizz
97
98
Fizz
Buzz

Defining the tool

TDD is basically a methodology or a software development process that is based on the repetition of the following tasks:

  • Write a simple test that defines an expected functionality/outcome
  • Make the test fail (it will fail as we haven’t written any code just yet!)
  • Write your code as simple as possible to make your test pass
  • Refactor your code and run the same test again (it should pass as even though is refactored the functionality should be the same.

Let’s get started ! (aka iteration 1)

We’ll start by writing the most simple unit test of all, a unit test that will output the first two integers of the list

 

An important thing to notice here: to compare Lists we must use CollectionAssert.AreEqual (instead of Assert.AreEqual)

And the method (which will make the test fail) is below:

 

Now let’s write the simplest possible code to make the test pass:

 

Iteration 2

Well, that was easy !, but not quite there yet, let’s now get the first three integers of the list, but as the third item is multiple of 3 we’ll have to output Fizz instead of the number 3

That means we have to take into account the following:

  • Instead of expecting a list of integers we’ll now expect a list of strings (something like “1”, “2”, “Fizz” so we can happily have them living in the same list)
  • We need to pass a number to our GetFizzBuzz method which will act as the ceiling

Remember always write the unit test first !

 

Now our code is not even compiling (as GetFizzBuzz doesn’t take any parameters yet), let’s fix that in both our first unit test (which will now test for a list of strings) and our GetFizzBuzz method which will take an argument as the ceiling:

 

 

Wow !, our two unit tests pass and we’re getting the first three items correctly, next step is to get the first 5 items (yes you got it: “1”, “2”, “Fizz”, “4”, “Buzz”)

Iteration 3

 

After running our test it fails, this is the message from our unit test framework:

TestFizzBuzz unit test fails

The expected list was “1”, “2”, “Fizz”, “4” and “Buzz” but we received “1”, “2”, “Fizz”, “4”, “5”, (hence the element at index 4 didn’t match). We know what do !, lets write the simplest code we can to make the test pass!

 

Good stuff, our three tests pass but our code is getting harder and harder to read (this is where the last step in each iteration comes on board: refactoring), refactoring means rearranging our code so its easily readable by us (humans); so how can we make this easier to read? I’m thinking of extracting some of the code to another function, let’s try that:

 

Isn’t this easier to read? Yes !, and running our unit tests confirm that we haven’t broken anything as all of them still pass !

Iteration 4

Ok, things are looking better now, the next challenge is to get the FizzBuzz output whenever a multiple of 3 and 5 is found (that is 15, 30, 45, 60, 75 and 90), let’s write the unit test first

 

As expected, our test fails, we get “Fizz” in the 15th position (14th if we talk about the 0-index lists) instead of “FizzBuzz”, let’s fix that.

 

Yes, it doesn’t look like the nicest code but remember we can always make it better in the refactoring part of the iteration.

After running all unit tests we can see that they all pass !

all unit tests pass

 

We can always run additional unit tests but I’m confident that these unit tests are enough to prove how TDD works and hopefully you’ll have a better idea on how this process can make your code more robust and modular at the same time.

Thanks for reading (a very long blog post) !

What makes a good unit test?

If you come across this post it may be because you’ve only started reading about unit tests and are thinking of implementing them (way to go!), or perhaps want a clearer definition of what it is and what it actually makes a good unit test, whatever your reason is I will hopefully be able to shed some light on it.

What is actually a unit test?

In plain English, a unit test can be defined as a short piece of code that we write in order to test another method/function by specifying a known input and obtaining an expected output.

Well, that may not have been the best definition but maybe an example would help.

Show me the code!

Let’s say we have a method that is meant to provide us with some sort of calculation (i.e. the total price after a 10% discount has been applied).

How do we know this code works as expected? (I know this is a really simple example but let’s image there are some complicated calculations involved). To test it we could for example have a web page that at the click of a button calls this function and displays the results, or have a console application that can call that function and display the results on the console (wow that sounds like a lot of effort, I think I’ll pass)

How about running a unit test? writing a unit test should not take long and we can get instant feedback, let’s give that a go

After running this unit test we can see that it fails !, but why? because in my CalculateTotalPrice method I’m returning the total discounted value, not the total price after the discount has been applied (yes silly mistake)

 

unit_test_fails

unit test fails

 

See what I mean by instant feedback? had I not run this unit test I would probably have received a call later on from my boss, and certainly not a happy one.

After fixing my method I re-run the unit test and I get a nice green mark, hooray!

unit test passes

unit test passes

 

So… What makes a good unit test?

You’ve probably guessed a couples of answers to this question by this point, let’s enumerate them:

  • Unit tests should be easy to write
  • Unit tests should be automated: (even though we didn’t cover automated unit tests in this blog they can run automatically as part of your build)
  • Unit tests should be repeatable: kind of what we just said above, it just means that we can run it over and over again with each build
  • Unit tests should add value to the product/project: Don’t just write unit tests for the sake of it, test the business logic of your application and not a function that adds up two numbers (that makes my example a bad unit test but you get the idea)
  • Unit tests should be independent to all others: if a unit test depends on another, then is not a unit test
  • Unit tests should test a unit of work (that is a single isolated method/function) and not more than that (otherwise it may be an integration test)
  • Unit tests should be clearly named following a pre-define naming convention (here is an example of unit test naming conventions)

 

P.S. we didn’t talk about TDD (Test Driven Development) as this would extend the original scope to this blog post but I will publish a blog post about that soon.

In the meantime, do you have any other ideas of what makes a good unit test?