Test-driven development of random algorithms
Robert Kern
robert.kern at gmail.com
Mon Nov 13 22:36:51 EST 2006
Steven D'Aprano wrote:
> I'm working on some functions that, essentially, return randomly generated
> strings. Here's a basic example:
>
> def rstr():
> """Return a random string based on a pseudo
> normally-distributed random number.
> """
> x = 0.0
> for i in range(12):
> x += random.random()
> return str(int(x)+6))
>
> I want to do test-driven development. What should I do? Generally, any
> test I do of the form
>
> assert rst() == '1'
>
> will fail more often than not (about 85% of the time, by my estimate). An
> easy work around would be to do this:
>
> assert rstr() in [str(n) for n in range(-6, 6)]
>
> but (1) that doesn't scale very well (what if rstr() could return one of
> a billion different strings?) and (2) there could be bugs which only show
> up probabilistically, e.g. if I've got the algorithm wrong, rstr() might
> return '6' once in a while.
>
> Does anyone have generic advice for the testing and development of this
> sort of function?
"Design for Testability". In library code, never call the functions in the
random module. Always take as an argument a random.Random instance. When
testing, you can seed your own Random instance and all of your numbers will be
the same for every test run.
This kind of design is A Good Thing(TM) outside of unit tests, too. They aren't
the only places where one might want to have full control over the sequence of
random numbers.
--
Robert Kern
"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
More information about the Python-list
mailing list