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
Newsletter
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

  • Stop Paying a Model to Make Decisions You Already Made
  • Why Incident Response Needs Memory, Not Just Intelligence
  • Event-Driven AI Systems With Kafka and Autonomous Agents
  • The Request Timed Out, But the Payment Succeeded: Building Retry-Safe Mobile APIs

Draft This article hasn't been published, so readers can't see it.

In moderation This article is waiting for review, so readers can't see it yet.

Deleted This article has been deleted, so readers can't see it.

  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
·
Mar. 09, 18 · Tutorial
Post on X (opens in a new tab) Share on LinkedIn (opens in a new tab)
18.7K Views

Join the DZone community Save articles, join the discussion, and download Refcards and Trend Reports with a free account.

Join for free Already a member? Log in

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

Loading comments

The comments didn't load

Please try again in a moment.

Likes

Loading

The next likes didn't load. Please try again.

The likes didn't load

Please try again in a moment.

See who liked this

Log in or join DZone for free to see who liked this article.

Log in Join for free
  • 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