doctests for interactive functions

  • Thread starter Brian van den Broek
  • Start date
B

Brian van den Broek

Hi all,

I have a module of classes for getting input from the user that
satisfies various constraints. For instance, one class is created with
a menu of option, presents them to the user, and rejects any input
other than a menu option; another ensures that the user's input is
interpretable as an integer between specified bounds, etc.

It is a module I wrote up when in the early stages of learning Python.
It's a bit ugly :) So, I am rewriting it, and this time also am
putting in unit tests (I am using doctest).

Since the classes are for getting input interactively, a
straightforward use of doctest is not going to work. (The tests won't
run automatically.) I've come up with a way to make it work, but I
would like to know from more experienced people if there are better
ways that I am overlooking.

All classes take an optional argument input_function that determines
how the class instance gets its input. If this is not provided, it
defaults to raw_input. doctest tests reassign it so that they can be
run automatically.


So, an actual interactive session might look like:
Yes or no?
What about?
You have entered 'What about?'.
You must enter a value in ['n', 'no', 'y', 'yes'].
(Case does not matter.)
Please try again.
Yes or no?
N

The corresponding doctest I've constructed looks like:
>>> inputs = ['NO', 'What about?']
>>> yn = IG.YesNo()
>>> yn.get(input_function=lambda: inputs.pop())
Yes or no?
You have entered 'What about?'.
You must enter a value in ['n', 'no', 'y', 'yes'].
(Case does not matter.)
Please try again.
Yes or no?False


That works fine as a unit test. But, it doesn't score too well on the
`executable documentation' metric, as there is the inputs.pop() in the
way, and the user input doesn't make it on to the screen.

Is there any way to make the doctests look more like actual
interactive sessions, while preserving their automatic runability?

Thanks and best,

Brian vdB
 
N

Neil Cerutti

All classes take an optional argument input_function that
determines how the class instance gets its input. If this is
not provided, it defaults to raw_input. doctest tests reassign
it so that they can be run automatically.

What I've done in these cases is create a file containing my test
input, and before running the doctests I remap sys.stdin to my
file of test data. Then you don't need test code cluttering up
your functions.
 
B

Brian van den Broek

Neil Cerutti said unto the world upon 02/08/2007 02:25 PM:
What I've done in these cases is create a file containing my test
input, and before running the doctests I remap sys.stdin to my
file of test data. Then you don't need test code cluttering up
your functions.


Hi Neil and all,

Thanks for the suggestion, Neil. I will look into it.

I am not worried about the test code cluttering up my module's source,
as I am using doctest.testfile to run doctests defined in a separate
file anyway. I am looking to produce illustrative examples for the
user manual which also can serve as tests. I'll play around and see if
remapping sys.stdin reduces the gap between the appearance of the
doctest examples and of actual use cases as compared to my current
approach.

Thanks again,

Brian vdB
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,992
Messages
2,570,220
Members
46,807
Latest member
ryef

Latest Threads

Top