[Tutor] unit testing raw_input()

Michael ms at cerenity.org
Wed Apr 19 01:15:51 CEST 2006


On Tuesday 18 April 2006 23:34, Andre Roberge wrote:
> Hi all-
>
> Suppose I had a function like the following:
>
> [ function that interacts with the outside world ]
...
> How could I go about to write an automated test for it?

You create a mock for raw_input, put the above code inside a module and rebind 
raw_input in the module before calling your function.

ie:
------------(CONTENTS of y_n.py)------------
def y_n(prompt="Answer yes or no"):
    while True:
        answer = raw_input(prompt)
        if answer in ['y', 'Y', 'yes']:
            print "You said yes!"
            break
        elif answer in ['n', 'N', 'no']:
            print "You said no!"
            break
        else:
            print "%s is an invalid answer."%answer
------------(END CONTENTS of y_n.py)------------

You can even create and test a mock in the command line interpreter, so here's 
a quick example:

>>> import y_n   # Import the module 
>>> def raw_input_mock(prompt): # create a mock
...     return "y"
...
>>> y_n.raw_input = raw_input_mock      # rebind the name inside the module
>>> y_n.y_n() # Run, this now calls our mock instead of the real raw_input
You said yes!

To my mind this is generally useful for testing error conditions with complex 
modules (select & socket spring to mind).

To do this properly with your module, it makes more sense for your function
to return strings, which would allow you to directly test the result.
Alternatively you could wrap print in a function and then mock that instead.

The key thing about a mock is that it simply provides the results you want. If 
it's important *how* the mock was called (eg you're testing correct use of a 
library), your mock could append parameters to a list for later comparision.

Eg
>>> mocktrace = []
>>> def raw_input_mock(prompt): # create a mock
...     mocktrace.append((prompt,))
...     return "y"
...

As I say though, this sort of thing is (IME) often more about testing the 
correct usage of something.

Regards,


Michael.


More information about the Tutor mailing list