Skip to main content
blog title image

4 minute read - TDD

TDD - Test Driven Development - Java JUnit FizzBuzz

Mar 4, 2018

TLDR; Four JUnit @Test methods to create a FizzBuzz solution using Test Driven Development (TDD) with Java Junit.

TDD Exercise - FizzBuzz

As part of a Sunday Morning practice session I used FizzBuzz as my coding exercise.

I’ve heard that this is used in programming interviews and I so I thought I’d try it.

FizzBuzz rules are documented here http://wiki.c2.com/?FizzBuzzTest

The video I created of the TDD session is at the bottom of this post.


First I:

  • created a test class
  • copied in the rules as a comment
  • formatted the rules to make it easy to understand
  • added some examples so that I could understand

My First Test

The first Test I wrote was:

@Test
public void fizzBuzzConvertorLeavesNormalNumbersAlone(){

    FizzBuzzConverter fizzBuzz = new FizzBuzzConverter();

    Assert.assertEquals("1", fizzBuzz.convert(1));
}

This forced me to create the FizzBuzzConverter class and convert method.

I added a second assertion to this test:

Assert.assertEquals("2", fizzBuzz.convert(2));

This forced me to actually implement the default code in convert:

return String.valueOf(toConvertToFizzBuzz);

Thoughts on My First Test

Some people don’t like multiple assertions in a Test.

Sometimes I do, sometimes I don’t.

Here, I didn’t mind:

  • the test name allowed me to have multiple assertions
  • I thought multiple test methods would make it harder to Grok

My Second Test

The second test was:

@Test
public void fizzBuzzConvertorMultiplesOfThree(){

    FizzBuzzConverter fizzBuzz = new FizzBuzzConverter();

    Assert.assertEquals("Fizz", fizzBuzz.convert(3));
}

This forced me to implement the ‘3’ division rule:

if(toConvertToFizzBuzz%3==0){
   return "Fizz";
}

I imagine that if you don’t know the modulus operator then FizzBuzz can be quite hard.

I learned modulus back in the day of 8 bit programming and have been using it for various boundary, clipping, and scrolling routines ever since.

My Third Test

The third test was:

@Test
public void fizzBuzzConvertorMultiplesOfFive(){

    FizzBuzzConverter fizzBuzz = new FizzBuzzConverter();

    Assert.assertEquals("Buzz", fizzBuzz.convert(5));
}

Much the same as the condition for number 3:

if(toConvertToFizzBuzz%5==0){
   return "Buzz";
}

At this point my convert method looks as follows:

public String convert(int toConvertToFizzBuzz) {

    if(toConvertToFizzBuzz%5==0){
       return "Buzz";
    }
    
    if(toConvertToFizzBuzz%3==0){
       return "Fizz";
    }
    
    return String.valueOf(toConvertToFizzBuzz);
}

Thoughts on Test 3

I have seen people create very complicated code for FizzBuzz.

I’m keeping it simple on the basis that. If I can get it working, then I can refactor it for efficiency or ’looking like a good programmer’ later.

Test 4

My Fourth Test was much the same.

@Test
public void multiplesOfBothThreeAndFive(){
   FizzBuzzConverter fizzBuzz = new FizzBuzzConverter();

   Assert.assertEquals("FizzBuzz", fizzBuzz.convert(15));
}

At this point though, when I looked at the convert method I started to think:

  • should I add a flag to check for fizz and buzz?
  • should I have a set of nested ifs?
  • perhaps I can use a tertiary operator for some ‘magic’

Instead I decided to keep it simple:

if(toConvertToFizzBuzz%15==0){
   return "FizzBuzz";
}

Thoughts on Test 4

I suspect that this is the point at which people ‘fail’ to implement FizzBuzz, because the code in the method becomes over complicated.

My @Test methods do not warrant any complicated code:

public String convert(int toConvertToFizzBuzz) {

    if(toConvertToFizzBuzz%15==0){
       return "FizzBuzz";
    }
    
    if(toConvertToFizzBuzz%5==0){
        return "Buzz";
    }
    
    if(toConvertToFizzBuzz%3==0){
        return "Fizz";
    }
    
    return String.valueOf(toConvertToFizzBuzz);
}

There is a priority to the conditions where:

  • 15 is higher priority because it is a combination of 3 and 5
  • 3 and 5 are equal priority and so it doesn’t matter which order they are in
  • String conversion is the default so is lower priority

In olden days we were taught to have a single return value per method. If I had written the code this way then it would be more complicated. Instead I return as soon as I’ve matched a condition.

The conditions are really as set of ‘guards’ to prevent fall through to the default operation.

Done

At this point I’m ‘done’.

Or at least I have an algorithm that will support the conversion of integers in the range 1 to 100 into Fizz, Buzz, Number or FizzBuzz

All I have to do is wrap it into something that will print out the values.

@Test
public void outputTheHundredFizzBuzzes(){

   FizzBuzzConverter fizzBuzz = new FizzBuzzConverter();
    for(int i=1; i<=100; i++){
       System.out.println(fizzBuzz.convert(i));
    }
}

I created it as an @Test for expediency and I can execute it from the IDE.

And then the tester kicks in

  • I have used TDD to design the algorithm.
  • I have not ’tested’ the output routine, I have executed it and seen the output from 1-100, but I don’t really have an Oracle to compare that to
  • I haven’t asserted on my acceptance criteria but I have seen the values match my output from running outputTheHundredFizzBuzzes

If this was a programming interview I might have to convert the outputTheHundredFizzBuzzes into a main method and run it, but the basic implementation of the requirements have been met.

As a tester I’m not sure I have convinced myself it ‘works’, but it ‘works’.

You can find all the code for this in the repo https://github.com/eviltester/fizzbuzz

Video

Slide Summary