SUT for all x < n.
(Pseudocode)
testRegular ->
assert(SUT[1] equals 1)
assert(SUT[2] equals 2)
assert(SUT[3] not equals 3)
...
testFizz ->
assert(SUT[1] not contains "Fizz")
assert(SUT[2] not contains "Fizz")
assert(SUT[3] contains "Fizz")
...
testBuzz ->
assert(SUT[1] not contains "Buzz")
assert(SUT[2] not contains "Buzz")
assert(SUT[3] not contains "Buzz")
...
Even though the above appears to test all the rules, it is not conclusive.
- For n = 15, the output might be either FizzBuzz or BuzzFizz
- We haven't tested for unwanted characters, eg SUT[3] == "FizzBlabla" would still pass
One solution is to add this:
testFizzBuzz ->
assert(SUT[1] not equals "FizzBuzz")
assert(SUT[2] not equals "FizzBuzz")
...
assert(SUT[15] equals "FizzBuzz")
...
All of this amounts to highly verbose tests. More test code decreases readability and maintainabity, and therefore lowers the value of the test. My point is that, in the case of fizzbuzz, not to test the rules individually, but test the observable output of fizzbuzz, making no assumptions about the rules.
testFizzBuzz ->
assert(SUT == ["1", "2", "Fizz", ...])
A oneliner that proves unequivocally the observable behaviour of fizzbuzz for x<n, surely is preferred to hundreds LoC that still allow wrong values to pass?
I'm not saying it is always better. Sometimes I test the behaviour as a whole, sometimes I test individual rules separately. This is a judgment call and should not be generalized.