Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing a card deck shuffler

Tags:

unit-testing

I have a class PlayingCard which represents a particular playing card. I have another class, Deck, which contains a list of PlayingCard objects. Deck has a shuffle() method that randomizes the card order.

I would like to write some unit tests for the shuffle() method, but I'm at a bit of a loss. I'd prefer the test to not care about the internals of just how the shuffle is done, but I want them to be good tests.

How do I best unit test when randomness is involved?

like image 611
Brandon Yarbrough Avatar asked Sep 18 '09 04:09

Brandon Yarbrough


2 Answers

One approach is to make statistical tests; after each shuffle check for correctness (the set of cards must not have been changed, only the order), and collect statistics about some random variables ("position of the 7 of diamonds", "is the 5 of clubs before or after the 8 of hearts", and the like) to be tested after a suitable number of shuffles by Student's t-test and other statistical hypothesis-testing approaches.

like image 53
Alex Martelli Avatar answered Sep 19 '22 15:09

Alex Martelli


I don't have particular ideas about unit testing this, but a quick note about the algorithm you use. It is very easy to naively and unknowingly create a biased shuffle algorithm. No need to reinvent the wheel—the Fisher-Yates shuffle will guarantee an unbiased shuffle, if implemented correctly.

There are easy pitfalls you might hit if you don't do FY properly:

  • Take each card i and swap it with another random card j in the deck where j can be any card, even one from an already-visited position. This is a biased shuffle.
  • Taking the output of an RNG mod 52 to get random card positions. Also leads to slight bias.
like image 40
John Kugelman Avatar answered Sep 18 '22 15:09

John Kugelman