sphinx.ext.doctest – 文档中的测试代码片段

在文档中包含代码片段并展示执行结果通常是有帮助的.但确保文档与代码保持同步是很重要的.

此扩展允许您以自然的方式在文档中测试代码片段.如果您像这里所示标记代码块, doctest 生成器将收集它们并将其作为doctest测试运行.

在每个文档中,您可以将每个片段分配给一个 .每个组由以下内容构成:

  • 零个或多个 setup code 块(例如,导入要测试的模块)

  • 一个或多个 测试

当使用 doctest 构建文档时,将为每个文档收集组,并依次运行,首先执行设置代码块,然后按文件中出现的顺序执行测试块.

有两种测试块:

  • doctest-style 块通过交替显示 Python 代码(包括解释器提示)和输出,模拟交互式会话.

  • code-output-style 块由一段普通的 Python 代码组成,并可选择性地包含该代码的输出.

指令

下面的 group 参数的解释如下:如果它为空,块将被分配给名为 default 的组.如果它是 * ,则块将被分配给所有组(包括 default 组).否则,它必须是一个以逗号分隔的组名列表.

.. testsetup:: [group]

一个设置代码块. 此代码在其他构建器的输出中不会显示,但在其所属组的文档测试之前执行.

.. testcleanup:: [group]

一个清理代码块.此代码在其他构建器的输出中不显示,但在其所属组的文档测试后执行.

Added in version 1.1.

.. doctest:: [group]

一个 doctest 风格的代码块.您可以使用标准的 doctest 标志来控制实际输出与您所提供的预期输出之间的比较.默认的标志集由 doctest_default_flags 配置变量指定.

此指令支持五个选项:

  • hide, a flag option, hides the doctest block in other builders. By default it is shown as a highlighted doctest block.

  • options, a string option, can be used to give a comma-separated list of doctest flags that apply to each example in the tests. (You still can give explicit flags per example, with doctest comments, but they will show up in other builders too.)

  • pyversion, a string option, can be used to specify the required Python version for the example to be tested. For instance, in the following case the example will be tested only for Python versions greater than 3.12:

    .. doctest::
       :pyversion: > 3.12
    

    支持以下操作数:

    • ~=: Compatible release clause

    • ==: Version matching clause

    • !=: Version exclusion clause

    • <=, >=: Inclusive ordered comparison clause

    • <, >: Exclusive ordered comparison clause

    • ===: Arbitrary equality clause.

    pyversion option is followed PEP-440: Version Specifiers.

    Added in version 1.6.

    在 1.7 版本发生变更: 支持的PEP-440运算符和表示法

  • trim-doctest-flags and no-trim-doctest-flags, a flag option, doctest flags (comments looking like # doctest: FLAG, ...) at the ends of lines and <BLANKLINE> markers are removed (or not removed) individually. Default is trim-doctest-flags.

注意,与标准的 doctests 一样,您需要使用 <BLANKLINE> 来表示预期输出中的空行.构建演示输出(HTML、LaTeX 等)时,会移除 <BLANKLINE> .

同样,您可以提供内联文档测试选项,如下所示:doctest:

>>> datetime.date.now()   # doctest: +SKIP
datetime.date(2008, 1, 1)

它们将在测试运行时得到尊重,但会从展示输出中剥离.

.. testcode:: [group]

一个用于代码输出风格测试的代码块.

此指令支持三个选项:

  • hide, a flag option, hides the code block in other builders. By default it is shown as a highlighted code block.

  • trim-doctest-flags and no-trim-doctest-flags, a flag option, doctest flags (comments looking like # doctest: FLAG, ...) at the ends of lines and <BLANKLINE> markers are removed (or not removed) individually. Default is trim-doctest-flags.

备注

testcode 块中的代码总是会一次性执行,无论它包含多少条语句.因此,对于裸表达式,将 生成输出 – 请使用 print .示例:

.. testcode::

   1+1         # this will give no output!
   print(2+2)  # this will give output

.. testoutput::

   4

另外,请注意,由于doctest模块不支持在同一代码片段中混合常规输出和异常消息,因此这也适用于testcode/testoutput.

.. testoutput:: [group]

最后一个 testcode 块的相应输出或异常消息.

此指令支持四个选项:

  • hide, a flag option, hides the output block in other builders. By default it is shown as a literal block without highlighting.

  • options, a string option, can be used to give doctest flags (comma-separated) just like in normal doctest blocks.

  • trim-doctest-flags and no-trim-doctest-flags, a flag option, doctest flags (comments looking like # doctest: FLAG, ...) at the ends of lines and <BLANKLINE> markers are removed (or not removed) individually. Default is trim-doctest-flags.

示例:

.. testcode::

   print('Output     text.')

.. testoutput::
   :hide:
   :options: -ELLIPSIS, +NORMALIZE_WHITESPACE

   Output text.

以下是指令用法的示例.通过 :rst :dir:`doctest` 进行的测试与通过 testcodetestoutput 进行的测试是等价的.:

The parrot module
=================

.. testsetup:: *

   import parrot

The parrot module is a module about parrots.

Doctest example:

.. doctest::

   >>> parrot.voom(3000)
   This parrot wouldn't voom if you put 3000 volts through it!

Test-Output example:

.. testcode::

   parrot.voom(3000)

This would output:

.. testoutput::

   This parrot wouldn't voom if you put 3000 volts through it!

有条件地跳过测试

skipif, a string option, can be used to skip directives conditionally. This may be useful e.g. when a different set of tests should be run depending on the environment (hardware, network/VPN, optional dependencies or different versions of dependencies). The skipif option is supported by all of the doctest directives. Below are typical use cases for skipif when used for different directives:

  • testsetup and testcleanup

    • 有条件地跳过测试设置和/或清理

    • 为每个环境自定义设置/清理代码

  • 示例测试

    • 有条件跳过测试及其输出验证

  • 测试代码

    • 有条件地跳过测试

    • 自定义各环境的测试代码

  • 测试输出

    • 条件跳过被跳过测试的输出断言

    • 期望根据环境产生不同的输出

The value of the skipif option is evaluated as a Python expression. If the result is a true value, the directive is omitted from the test run just as if it wasn’t present in the file at all.

可以使用 doctest_global_setup 配置选项将表达式赋值给变量,从而避免重复表达式,这样就可以使用该变量.

这是一个示例,如果未安装 Pandas,则跳过某些测试:

conf.py
extensions = ['sphinx.ext.doctest']
doctest_global_setup = '''
try:
    import pandas as pd
except ImportError:
    pd = None
'''
contents.rst
.. testsetup::
   :skipif: pd is None

   data = pd.Series([42])

.. doctest::
   :skipif: pd is None

   >>> data.iloc[0]
   42

.. testcode::
   :skipif: pd is None

   print(data.iloc[-1])

.. testoutput::
   :skipif: pd is None

   42

配置

doctest扩展使用以下配置值:

doctest_default_flags

默认情况下,这些选项是启用的:

  • ELLIPSIS, allowing you to put ellipses in the expected output that match anything in the actual output;

  • IGNORE_EXCEPTION_DETAIL, causing everything following the leftmost colon and any module information in the exception name to be ignored;

  • DONT_ACCEPT_TRUE_FOR_1, rejecting “True” in the output where “1” is given – the default behavior of accepting this substitution is a relic of pre-Python 2.2 times.

Added in version 1.5.

doctest_show_successes

默认为 True .控制是否报告成功.

对于一个有很多文档测试的项目,将这个设置为 False 可能很有用,以便只突出显示失败的情况.

Added in version 7.2.

doctest_path

将会在使用doctest构建器时添加到:data:sys.path 的目录列表.(确保包含绝对路径.)

doctest_global_setup

Python代码会被当作放置在每个被测试的文件和每个组的 testsetup 指令中.您可以用它来导入在您的文档测试中总是需要的模块.

Added in version 0.6.

doctest_global_cleanup

在每个被测试的文件和每个组中,Python 代码被视为放置在 testcleanup 指令中的内容.你可以使用它来删除测试留下的任何临时文件.

Added in version 1.1.

doctest_test_doctest_blocks

如果这是一个非空字符串(默认值为 'default' ),标准的reStructuredText doctest块也将被测试.它们将被分配到给定的组名.

reStructuredText的doctest块仅仅是将doctest放入自己单独的段落中,如下所示:

Some documentation text.

>>> print(1)
1

Some more documentation text.

(注意,未使用特殊的 :: 来引入 doctest 块;docutils 从前导的 >>> 识别它们.另外,也没有使用额外的缩进,尽管这没有坏处.)

如果此值保持为默认值,则上述代码片段将被 doctest 构建器解释为如下内容:

Some documentation text.

.. doctest::

   >>> print(1)
   1

Some more documentation text.

此功能使您可以轻松测试包含在 autodoc 扩展中的文档字符串中的 doctests,而无需使用特殊指令标记它们.

注意,reStructuredText的doctest块中不能有空行.它们会被解释为一个块结束和另一个块开始.此外,移除 <BLANKLINE># doctest: 选项仅在:rst:dir:doctest 块中有效,但您可以设置:confval:trim_doctest_flags 以在所有包含Python控制台内容的代码块中实现这一点.