Test List (Requirements)

  • When a number is divisible by 3 return Fizz
  • When a number is divisible by 5 return Buzz
  • When a number is divisible by 3 & 5 return FizzBuzz
  • All other numbers return that number
  • Only accept whole integers in the range 0 to Integer.MAX
TDD Cycle

Step 2 - Write a failing test

  • Pick a test from the list, pick something easy to get going, doesn't have to be in any particular order
  • Write a Unit Test, using the test name to describe the expected behaviour
  • Write only enough Production code to ensure the test compiles without error (no logic)
  • Run the test - It should fail
public class FizzBuzzProcessorTest {
    @Test
    public void shouldReturnFizzWhenNumberDivisibleBy3() {
        // Multiple asserts, but all with a single concept
        assertEquals( "Fizz", FizzBuzzProcessor.processNumber( 3 ) );
        assertEquals( "Fizz", FizzBuzzProcessor.processNumber( 6 ) );
        assertEquals( "Fizz", FizzBuzzProcessor.processNumber( 9 ) );
    }
}
                                
public class FizzBuzzProcessor {
    public static String processNumber( int number ) {
        throw new UnsupportedOperationException( "Not implemented" );
    }
}
                                

Test Results: FAIL (0 pass, 1 fail)

Comments

Its very important the the test compile and fail as this sets a very clear goal & boundary for the production code.
We aim to write very clear and concise code avoiding 'the zone' and focusing purely on the immediate problem
When focusing on a single test, we are not overloading or overwhelming ourselves with a 'greater problem', but instead breaking the problem into small manageable chunks.

This is a simplistic example, but you should see how this can be applied to bigger, more complex problems.

Notice the test case contains multiple asserts, but still conforms to a single concept, making identification of the cause of test failure easier to isolate