An introduction to :mod:`doctest2` for existing users of :mod:`doctest` ======================================================================= .. include:: intro.rst Backwards compatibility ======================= By and large, doctest2 is backwards compatible. All, or nearly all, examples should be tested and compared in the same way. In cases where they are run differently, doctest2 aims to be "better", and never break anything. (However, some tests that failed before -- incorrectly -- may pass under doctest2) Running ======= To run doctest2 on a file, use :samp:`python -m doctest2 {my_file}`, or use the invocation API specified later below. New features ============ Python literal evaluation ------------------------- The classic failure case of doctest is that dicts aren't ordered, so that the following doctest may fail:: >>> {-1: 0, 1: 2} {-1: 0, 1: 2} doctest2 adds a Python literal evaluation mode which takes the entire output of a function, and the expected output, and parses each as a Python literal. In this way, the example is less fragile: .. doctest:: >>> {-1: 0, 1: 2} # doctest: +AST_LITERAL_EVAL {-1: 0, 1: 2} Session-wide doctest options ---------------------------- Often a certain option will be common throughout an entire example session, or a large part of it. doctest2 adds session-global doctest options. Where regular options are given as ``+FOO``, global options are given as ``+!FOO``. For example: .. doctest :: >>> 1 # doctest: +!SKIP 2 >>> 1/0 >>> 0/0 # this is the last skipped doctest before... >>> 1 # doctest: -!SKIP 1 Exceptions and output --------------------- One of the more noticeable omissions in doctest is the inability to write a testable example of using a function that prints some output before it raises an exception. doctest2 allows you to specify both output _and_ exception: .. doctest :: >>> print('Hello, world!'); 1/0 Hello, world! Traceback (most recent call last): ... ZeroDivisionError: integer division or modulo by zero From Python to sh ================= The most significant addition doctest2 makes to doctest is the ability to test more than just Python interactive sessions. doctest2 can also test example shell sessions, too! Doctest directives look something like this: .. doctest:: >>> print(1) 1 This could be copy-pasted from an interactive Python session. When passed to :mod:`doctest2`, :mod:`doctest2` executes the statement ``print(1)`` and checks whether the output is ``1``. Extending over to multiple lines is done the same as in the interactive interpreter: .. doctest:: >>> print( ... 1) 1 :mod:`doctest2`'s biggest change is that interactive sessions are no longer limited to Python. In particular, POSIX ``sh`` and Windows ``cmd`` have been added, and both use a different prompt value. Where Python doctests use ``>>>`` and ``...``, sh doctests use ``$`` and ``>``, and cmd doctests use ``cmd>`` and ``?``. For example: .. doctest:: $ python3 -c "print(1)" 1 .. doctest:: cmd> python3 -c "print(1)" 1 This does a similar check, but runs it against ``sh`` and ``cmd``. .. note:: ``cmd`` support is a little shaky, and probably always will be. Even the lowest common denominator shell, ``sh``, offers some features that ``cmd`` does not. (For example: inline comments, and parsing error detection) Specifying languages to :mod:`doctest2` --------------------------------------- .. doctest:: :hide: >>> from doctest2.languages import languages # test name works alright. When requesting that doctest2 run a file to test, the languages that are to be tested must also be tested. In general, doctest2 will default to checking as many language as it knows about. If only _some_ should be tested, doctest2 needs to know which ones. The :mod:`doctest2.languages` package contains the various languages :mod:`doctest` can understand. For now, that is ``python`` (specifically, Python 3.x), ``sh``, and ``cmd``. Each language is represented by an object that :mod:`doctest2` can use to handle doctests in that language (``doctest2.languages.sh``, ``doctest2.languages.cmd``, ``doctest2.languages.python``). A list of all available language objects is available at :data:`doctest2.languages.languages`. .. todo:: document language addition etc. The move to supporting multiple languages comes with some cost in flexibility. In :mod:`doctest`, every doctest function accepted an instantiated :obj:`finder` or :obj:`parser` parameter that emulated :class:`doctest2.DocTestFinder` or :class:`doctest2.DocTestParser` respectively. This doesn't work in doctest2, because these classes don't know how different languages parse. In addition some arguments that used to make sense for all doctests only make sense for some. The :obj:`globs` parameter does not make sense for and isn't used for shell tests. This will be changed around in the future. The updated Python invocation API ................................. .. autofunction:: doctest2.testmod .. autofunction:: doctest2.testfile .. autofunction:: doctest2.run_docstring_examples