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!
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.
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.
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).
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With