DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Testing Approaches for Java Enterprise Applications With Jakarta NoSQL and Jakarta Data
  • Mastering Unit Testing and Test-Driven Development in Java
  • Creating Your Swiss Army Knife on Java Test Stack
  • I Don’t TDD: Pragmatic Testing With Java

Trending

  • Building Enterprise-Grade Real-Time IoT Dashboards with Vue 3, MQTT, and Kafka
  • OpenAPI From Code With Spring and Java: A Recipe for Your CI
  • Catching Data Perimeter Drift Before It Reaches Production
  • The Hidden Cost of Overprivileged Tokens: Designing Messaging Platforms That Assume Compromise
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Testing, Tools, and Frameworks
  4. TDD - Test Driven Development - Java JUnit FizzBuzz

TDD - Test Driven Development - Java JUnit FizzBuzz

In this article, we give a common programming interview question the TDD treatment, but from a tester's angle.

By 
Alan Richardson user avatar
Alan Richardson
·
Mar. 09, 18 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
18.4K Views

Join the DZone community and get the full member experience.

Join For Free

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.

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 a 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.

Video


Testing Test-driven development Java (programming language) JUnit

Published at DZone with permission of Alan Richardson. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Testing Approaches for Java Enterprise Applications With Jakarta NoSQL and Jakarta Data
  • Mastering Unit Testing and Test-Driven Development in Java
  • Creating Your Swiss Army Knife on Java Test Stack
  • I Don’t TDD: Pragmatic Testing With Java

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook