I’m working on a small project for myself at the moment and I’m using it as an opportunity to get acquainted with unit testing and maintaining proper documentation.
I have a Deck class with represents a deck of cards (it’s very simple and, to be honest, I can be sure that it works without a unit test, but like I said I’m getting used to using unit tests) and it has a shuffle() method which changes the order of the cards in the deck.
The implementation is very simple and will certainly work:
public void shuffle()
{
Collections.shuffle(this.cards);
}
But, how could I implement a unit test for this method. My first thought was to check if the top card of the deck was different after calling shuffle() but there is of course the possibility that it would be the same. My second thought was to check if the entire order of cards has changed, but again they could possibly be in the same order. So, how could I write a test that ensures this method works in all cases? And, in general, how can you unit test methods for which the outcome depends on some randomness?
Cheers,
Pete
Asserting whether your shuffle method actually shuffles the cards is very hard if not impossible. Default random number generators are only random to a certain degree. It’s impossible to test whether you’re satisfied with this degree of randomness because it would take too much time. What you’re actually testing is the random number generator itself which doesn’t make much sense.
What you can test however, are the invariants of this method.
You can of course create a test that checks that in a sequence of
nshuffles there are no duplicate decks returned. But once in a while this test may fail (however unlikely, as already stated in other answers).Something else to take into account is the random number generator itself. If this is just a toy project,
java.util.Randomis sufficient. If you intend to create some online card game, consider usingjava.security.SecureRandom.