Publicidade - Adsense

TDD - Test Driven Development - Java JUnit FizzBuzz


  • Moderador

    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.

    <a name=“more”></a>

    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:

    @Testpublic 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:

    @Testpublic 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:

    @Testpublic 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.

    @Testpublic 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.

    @Testpublic 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

    youtu.be/DWQgJqzkhvk


 

Publicidade - Adsense

status at

37
Online

2.9k
Usuários

1.7k
Tópicos

5.7k
Posts

});