Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Test-driven development of random algorithms

Reply
Thread Tools

Test-driven development of random algorithms

 
 
Steven D'Aprano
Guest
Posts: n/a
 
      11-14-2006
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?


--
Steven D'Aprano

 
Reply With Quote
 
 
 
 
Robert Kern
Guest
Posts: n/a
 
      11-14-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

 
Reply With Quote
 
 
 
 
Ben Finney
Guest
Posts: n/a
 
      11-14-2006
Robert Kern <(E-Mail Removed)> writes:

> Steven D'Aprano wrote:
> > 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.


Even better, you can pass a stub Random instance (that fakes it) or a
mock Random instance (that fakes it, and allows subsequent assertion
that the client code used it as expected). This way, you can ensure
that your fake Random actually gives a sequence of numbers designed to
quickly cover the extremes and corner cases, as well as some normal
cases.

This applies to any externality (databases, file systems, input
devices): in your unit tests, dont pass the real externality. Pass a
convincing fake that will behave entirely predictably, but will
nevertheless exercise the functionality needed for the unit tests.

This is one of the main differences between unit tests and other
kinds. With unit tests, you want each test to exercise as narrow a set
of the client behaviour as feasible. This means eliminating anything
else as a possible source of problems. With other tests -- stress
tests, acceptance tests, and so on -- you want to exercise the entire
application stack, or some significant chunk of it.

--
\ "It is the mark of an educated mind to be able to entertain a |
`\ thought without accepting it." -- Aristotle |
_o__) |
Ben Finney

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Math.random() and Math.round(Math.random()) and Math.floor(Math.random()*2) VK Javascript 15 05-02-2010 03:43 PM
random.random(), random not defined!? globalrev Python 4 04-20-2008 08:12 AM
Random "The IListSource does not contain any datasources" and more (Crashing a live site at random, twice a week or so) Lars-Erik Aabech ASP .Net 8 04-28-2005 07:52 AM
Random not really random... Maziar Aflatoun ASP .Net 4 08-05-2004 01:26 AM
Random NOt random? Darren Clark ASP .Net 3 06-24-2004 05:23 PM



Advertisments