Simulte user input using doctest

Steven Taschuk staschuk at
Fri Jun 27 15:57:25 CEST 2003

Quoth Bartolomé Sintes Marco:
> Is it possible to simulate user input in a doctest docstring? For example, I
> want to test if this module writes "Andy" when the user writes "Andy". What
> would be the docstring?
> def askyourname():
>     print "What's your name?",
>     myname = raw_input()
>     print myname

Redefining raw_input as Terry suggested is conceivable.  Note,
though, that the simplest approach won't work:

    def foo():
        >>> def bar():
        ...    return 18
        >>> foo()
        return bar()

    def bar():
        return 3

This test fails because the new bar is not defined in any
lexically enclosing scope of foo.  You could do, say,

    >>> def bar():
    ...    return 18
    >>> foo.func_globals['bar'] = bar
    >>> foo()

instead, but this is very hackish.

A better approach IMO is to make the function you want to test
more flexible:

    def foo(inputfunc=raw_input):
        print "What's your name?",
        name = inputfunc()
        print name

Now you can call foo with your own input function instead of
raw_input, and the test is easy:

    >>> foo(inputfunc=lambda: "Andy")
    What's your name? Andy

Such a technique can be considered to fall under the principle
"design for testing": write your code in such a way that it's easy
to test.  (Advocates of test-driven development will observe that
their methodology produces such code by construction.)

Steven Taschuk                            staschuk at
"Our analysis begins with two outrageous benchmarks."
  -- "Implementation strategies for continuations", Clinger et al.

More information about the Python-list mailing list