In the last note, I outlined the basic design of the dice simulator, and also mentioned that I had built some unit tests. Some of you may be asking, “How do you run repeatable tests on something that’s random?” It’s a good question, and one that uses a technique that it’s good to be familiar with — specifically, the concept of a random number generator seed.
Some background: Random number generators on computers aren’t truly random. Instead they use a pseudo random number generation (PRNG) algorithm that appears random, but is actually deterministic (or predictable). The thing to remember is that a PRNG will produce the exact same sequence of numbers if it is initialized with the same seed. In practice, most PRNGs are seeded with the low order bits of the current time, or some other rapidly changing device characteristics… and because of this, they appear to produce random results. However, you can also override this default and initialize them with a given seed instead. If you do this, they will produce the same numbers… every time. This is super helpful for testing, or even for reproducing a simulation run for debugging purposes.
You can see an example of this with an excerpt of initializing the seed in
SimpleHand and then also in the unit tests I built for the
class SimpleHand: def __init__(self, num_sides: int = 6, num_dice: int = 2, seed: int = None): self.rng = random.Random(seed) ...
from unittest import TestCase from core.hand import SimpleHand, YahtzeeHand TEST_SEED = 1234 class TestSimpleHand(TestCase): def test_roll_selected(self): h = SimpleHand(num_sides=6, num_dice=3, seed=TEST_SEED) self.assertEqual((4, 1, 1), h.get()) h.roll_selected([1, 2]) self.assertEqual((4, 1, 5), h.get()) h.roll_selected([0, 1]) self.assertEqual((1, 6, 5), h.get()) h.roll_selected() self.assertEqual((1, 6, 6), h.get()) ...
This setup allows us to build unit tests that can run over and over again, and always give the same results. Hooray!
Next, we’ll look at running a few quick simulations to make sure that the results from our project actually match what probability theory says should be happening when we roll a bunch of dice.