A few weeks back in our weekly coding kata we attempted the minesweeper challenge. (Coding Katas are quick training coding sessions). We created a few methods to create a board, add the right number of mines etc. We reached a point which we had to shuffle the board, so how do we test that the shuffling actually happened. Someone suggested that we can generate 2 shuffled boards and simply compare them, the problem with that approach is that there is always the probability that the test will fail intermittently. We could make the boards massive like 1000×1000 so even with a single mine, the test will fail once every 1 000 000 runs, increasing the mines will make the test even more reliable but to compare the boards we will need to do 2 000 000 comparisons, I think we can do better.
The truth is that is really hard or even impossible to test non-deterministic code, so how should we proceed? What are our options?
Approach 1 a probabilistic execution like the suggestion I described above. The issues with this approach are that it is slow and there is always even a small probability the unit test to fail intermittently.
Approach 2 attempt to prove the algorithm using a mathematical approach. Although this approach will guarantee correctness it is not a mainstream technique.
Approach 3 isolate the non-deterministic parts of the application and try to remove the randomness. Removing the randomness it is not something that can always be done but in our example above it was fairly straightforward.
Let’s attempt to implement approach 3, here is the class MineSweeper , note that mines are marked with an “X” and empty squares are marked with a “.”.
The first step in our example was to create a new class that would be responsible to shuffle the board lets call it BoardShuffler. BoardShuffler simply swaps every square with a random square. Random number generators usually accept a seed. The seed allows us to control the randomness and create a unit test that it is predictable. I have created an interface called IShuffler to allow me to mock this inline as an example but using a framework like Mockito will be my recommendation.
Here is simple test that demonstrates the approach. Obviously you will need more than a single unit test for this class but the additional tests should be straight forward.
The second step is to use dependency injection and use the BoardShuffler in the minesweeper class.
Writing a unit test is straightforward using a mock to check that the BoardShuffler has been called would do the trick.The testing of non-deterministic code can be tricky but DI can be really helpful and allows us to unit test parts of our application that we would have left without any unit test coverage. Again the topic is much more complex but I hope this blog gives you some assistance how to approach the problem.