summaryrefslogtreecommitdiff
path: root/doc/en/doctest.rst
blob: 2ee7110b3c4e278dc329be6670cfa8e554ed3e9f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

Doctest integration for modules and test files
=========================================================

By default all files matching the ``test*.txt`` pattern will
be run through the python standard ``doctest`` module.  You
can change the pattern by issuing::

    pytest --doctest-glob='*.rst'

on the command line. Since version ``2.9``, ``--doctest-glob``
can be given multiple times in the command-line.

.. versionadded:: 3.1

    You can specify the encoding that will be used for those doctest files
    using the ``doctest_encoding`` ini option:

    .. code-block:: ini

        # content of pytest.ini
        [pytest]
        doctest_encoding = latin1

    The default encoding is UTF-8.

You can also trigger running of doctests
from docstrings in all python modules (including regular
python test modules)::

    pytest --doctest-modules

You can make these changes permanent in your project by
putting them into a pytest.ini file like this:

.. code-block:: ini

    # content of pytest.ini
    [pytest]
    addopts = --doctest-modules

If you then have a text file like this::

    # content of example.rst

    hello this is a doctest
    >>> x = 3
    >>> x
    3

and another like this::

    # content of mymodule.py
    def something():
        """ a doctest in a docstring
        >>> something()
        42
        """
        return 42

then you can just invoke ``pytest`` without command line options::

    $ pytest
    =========================== test session starts ============================
    platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y
    rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
    collected 1 item
    
    mymodule.py .                                                        [100%]
    
    ========================= 1 passed in 0.12 seconds =========================

It is possible to use fixtures using the ``getfixture`` helper::

    # content of example.rst
    >>> tmp = getfixture('tmpdir')
    >>> ...
    >>>

Also, :ref:`usefixtures` and :ref:`autouse` fixtures are supported
when executing text doctest files.

The standard ``doctest`` module provides some setting flags to configure the
strictness of doctest tests. In pytest, you can enable those flags using the
configuration file. To make pytest ignore trailing whitespaces and ignore
lengthy exception stack traces you can just write:

.. code-block:: ini

    [pytest]
    doctest_optionflags= NORMALIZE_WHITESPACE IGNORE_EXCEPTION_DETAIL

pytest also introduces new options to allow doctests to run in Python 2 and
Python 3 unchanged:

* ``ALLOW_UNICODE``: when enabled, the ``u`` prefix is stripped from unicode
  strings in expected doctest output.

* ``ALLOW_BYTES``: when enabled, the ``b`` prefix is stripped from byte strings
  in expected doctest output.

As with any other option flag, these flags can be enabled in ``pytest.ini`` using
the ``doctest_optionflags`` ini option:

.. code-block:: ini

    [pytest]
    doctest_optionflags = ALLOW_UNICODE ALLOW_BYTES


Alternatively, it can be enabled by an inline comment in the doc test
itself::

    # content of example.rst
    >>> get_unicode_greeting()  # doctest: +ALLOW_UNICODE
    'Hello'

By default, pytest would report only the first failure for a given doctest.  If
you want to continue the test even when you have failures, do::

    pytest --doctest-modules --doctest-continue-on-failure


.. _`doctest_namespace`:

The 'doctest_namespace' fixture
-------------------------------

.. versionadded:: 3.0

The ``doctest_namespace`` fixture can be used to inject items into the
namespace in which your doctests run. It is intended to be used within
your own fixtures to provide the tests that use them with context.

``doctest_namespace`` is a standard ``dict`` object into which you
place the objects you want to appear in the doctest namespace::

    # content of conftest.py
    import numpy
    @pytest.fixture(autouse=True)
    def add_np(doctest_namespace):
        doctest_namespace['np'] = numpy

which can then be used in your doctests directly::

    # content of numpy.py
    def arange():
        """
        >>> a = np.arange(10)
        >>> len(a)
        10
        """
        pass


Output format
-------------

.. versionadded:: 3.0

You can change the diff output format on failure for your doctests
by using one of standard doctest modules format in options
(see :data:`python:doctest.REPORT_UDIFF`, :data:`python:doctest.REPORT_CDIFF`,
:data:`python:doctest.REPORT_NDIFF`, :data:`python:doctest.REPORT_ONLY_FIRST_FAILURE`)::

    pytest --doctest-modules --doctest-report none
    pytest --doctest-modules --doctest-report udiff
    pytest --doctest-modules --doctest-report cdiff
    pytest --doctest-modules --doctest-report ndiff
    pytest --doctest-modules --doctest-report only_first_failure