Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can python doctest ignore some output lines?

Tags:

python

doctest

I'd like to write a doctest like this:

""" >>> print a.string()           foo : a           bar : b          date : <I don't care about the date output>           baz : c """ 

Is there any way to do this? I think it would make more sense to switch to unittest, but I'm curious whether it's possible to specify a range of output that shouldn't be matched for the test in doctest.

Thanks!

like image 305
cjb Avatar asked Jun 21 '09 17:06

cjb


People also ask

Can we handle unpredictable output using doctest in Python?

When the tests include values that are likely to change in unpredictable ways, and where the actual value is not important to the test results, you can use the ELLIPSIS option to tell doctest to ignore portions of the verification value.

What is a doctest in Python?

doctest is a module included in the Python programming language's standard library that allows the easy generation of tests based on output from the standard Python interpreter shell, cut and pasted into docstrings.


2 Answers

With doctest.ELLIPSIS, you can use ... to mean "match any string here". You can set doctest options with a doctest directive, to make it active for just one test case: one example in the online docs is:

>>> print range(20) # doctest:+ELLIPSIS [0, 1, ..., 18, 19] 

If you want a doctest option to be active throughout, you can pass it as the optionflags= argument to whatever doctest functions you use, e.g. doctest.testfile. (You can pass multiple option flags there by using the | operator to bit-or them).

like image 103
Alex Martelli Avatar answered Oct 31 '22 13:10

Alex Martelli


Responding to questions about "how can we ignore the whole line": yes, the fact that "..." also looks like a continuation like makes it hard to ignore the entire output. You can use "#doctest: +SKIP" if you just want to skip the example entirely, but that won't work if you are relying on its side-effects. If you really need to do this, I suppose you could monkey-patch the doctest module itself, though I wouldn't particularly recommend it:

>>> import doctest >>> doctest.ELLIPSIS_MARKER = '-etc-' >>> print 12 # doctest: +ELLIPSIS -etc- 

(this test passes.)

Or you could temporarily suppress stdout and/or stderr:

>>> # Suppress stdout >>> import sys >>> class DevNull: ...     def noop(*args, **kwargs): pass ...     close = write = flush = writelines = noop >>> sys.stdout = DevNull() >>> # Run a test and ignore output (but we need its side effects) >>> print 12 # NOTE: stdout is suppressed! >>> # Restore stdout >>> sys.stdout = sys.__stdout__ 

(this test also passes.)

like image 35
Edward Loper Avatar answered Oct 31 '22 12:10

Edward Loper