In this article you will learn about the various doctest
directives and how to use them. This will not teach you the basics of doctest
, for that you can view the following article:
We use directives when we want to control the default behavior of doctest
for a given test. They are written as specially formatted comments at the end of a test.
They have the following syntax:
# doctest: +<behavior>
The behavior name can be preceded by either a plus or a minus sign . A plus sign enables the behavior, while the minus sign disables the behavior.
Let us now see some of the directives in practice.
Ignoring part of the test result
To make doctest
ignore irrelevant parts of the results yielded by a test, we can use the +ELLIPSES
directive.
Consider the following example:
#foo.py
def my_func():
'''
>>> 'This is a very long piece of text' # doctest: +ELLIPSIS
'This is ... text'
>>> [i for i in range(1000)] # doctest: +ELLIPSIS
[0, 1, 2, 3...997, 998, 999]
'''
We can run the tests by calling the doctest
with the following command:
python -m doctest foo.py -v
When you run the above command, you will get an output that is similar to one shown below:
Trying:
'This is a very long piece of text' # doctest: +ELLIPSIS
Expecting:
'This is ... text'
ok
Trying:
[i for i in range(1000)] # doctest: +ELLIPSIS
Expecting:
[0, 1, 2, 3...997, 998, 999]
ok
1 items had no tests:
foo
1 items passed all tests:
2 tests in foo.my_func
2 tests in 2 items.
2 passed and 0 failed.
Test passed.
As shown above, by using the +ELLIPSIS
directive we avoided typing the expected results in full, instead we just type only the relevant part that depicts how the entire result should look like.
Normalizing whitespaces
Whitespaces (spaces, newlines, tabs, e.t.c) can be troublesome and unnecessarily inconvenient to write. We can use the +
NORMALIZE_WHITESPAC
E directive to tell doctest
to "noramalize" white spaces in both the expected and the actual results. This basically means that multiple adjacent whitespaces are transformed into a single space.
Consider the following example:
#foo.py
def my_func():
'''
>>> 'Hello, World' # doctest: +NORMALIZE_WHITESPACE
'Hello, World'
>>> [ i for i in range(10)] # doctest: +NORMALIZE_WHITESPACE
[0, 1, 2,
3, 4, 5,
6, 7, 8, 9]
'''
When you run the above example, you will see that both tests passes.
Trying:
'Hello, World' # doctest: +NORMALIZE_WHITESPACE
Expecting:
'Hello, World'
ok
Trying:
[ i for i in range(10)] # doctest: +NORMALIZE_WHITESPACE
Expecting:
[0, 1, 2,
3, 4, 5,
6, 7, 8, 9]
ok
1 items had no tests:
foo
1 items passed all tests:
2 tests in foo.my_func
2 tests in 2 items.
2 passed and 0 failed.
Test passed.
Skip a test entirely
Sometimes we may want some tests to be skipped. We can achieve this by using the +SKIP
directive.
def my_func():
'''
>>> 1 + 1
2
>>> 2 + 2 #doctest: +SKIP
3
'''
Running the above tests will yield the following output.
Trying:
1 + 1
Expecting:
2
ok
1 items had no tests:
foo
1 items passed all tests:
1 tests in foo.my_func
1 tests in 2 items.
1 passed and 0 failed.
Test passed.
As you can see from the above output, the second test where we used the +SKIP
directive is ignored.
Other doctest Directives
The following tables summarizes other directives and what they do.
+DONT_ACCEPT_TRUE_FOR_1 |
makes doctest treat True and 1 as different values, instead of treating them as matching as it normally does. |
+IGNORE_EXCEPTION_DETAIL |
Makes exceptions match if the exception type is the same, even if the rest parts do not match. |
+DONT_ACCEPT_BLANKLINE |
Makes doctest forget about the special meaning of <BLANKLINE> |
+REPORT_ONLY_FIRST_FAILURE |
Doctest will avoid printing out failure reports on those tests after it is applied, if a failure report has already been printed |