Monday, July 29, 2019

Playing Fizzbuzz with property-based testing

Introduction.

Lately, I’ve been playing a bit with property-based testing.

I practised doing the FizzBuzz kata in Clojure and used the following constraints for fun[1]:

  1. Add one property at a time before writing the code to make the property hold.
  2. Make the failing test pass before writing a new property.

The kata step by step.

To create the properties, I partitioned the first 100 integers according to how they are transformed by the code. This was very easy using two of the operations on sets that Clojure provides (difference and intersection).

The first property I wrote checks that the multiples of 3 but not 5 are Fizz:

and this is the code that makes that test pass:

Next, I wrote a property to check that the multiples of 5 but not 3 are Buzz (I show only the new property for brevity):

and this is the code that makes the new test pass:

Then, I added a property to check that the multiples of 3 and 5 are FizzBuzz:

which was already passing with the existing production code.

Finally, I added a property to check that the rest of numbers are just casted to a string:

which Id made pass with this version of the code:

The final result.

These are the resulting tests where you can see all the properties together:

You can find all the code in this repository.

Conclusions.

It was a lot of fun doing this kata. It is a toy example that didn’t make me dive a lot into clojure.check’s generators documentation because I could take advantage of Clojure’s set functions to write the properties.

I think the resulting properties are quite readable even if you don’t know Clojure. On the other hand, the resulting implementation is probably not similar to the ones you’re used to see, and it shows Clojure’s conciseness and expressiveness.

Footnotes:

[1] I'm not saying that you should property-based testing with this constraints. They probably make no sense in real cases. The constraints were meant to make it fun.