sphinx.ext.doctest -- 文档中的测试片段

在文档中包含代码片段并演示执行它们的结果通常很有帮助。但是确保文档与代码保持最新是很重要的。

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

在每个文档中,可以将每个代码段分配给一个 。每组包括:

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

  • 一个或多个 test

当使用 doctest 构建器构建文档时,将为每个文档收集组并逐个运行,首先执行安装代码块,然后按它们在文件中出现的顺序执行测试块。

有两种测试块:

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

  • code-output-style 块由一段普通的Python代码和一段可选的该代码的输出组成。

指令

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

.. testsetup:: [group]

setup code块。此代码不会显示在其他生成器的输出中,而是在它所属组的doctest之前执行。

选项

:skipif: condition (text)

如果python表达式 condition 为True,则跳过该指令。请参阅 有条件地跳过测试

.. testcleanup:: [group]

清除代码块。此代码不会显示在其他生成器的输出中,而是在它所属组的doctest之后执行。

在 1.1 版本加入.

选项

:skipif: condition (text)

如果python表达式 condition 为True,则跳过该指令。请参阅 有条件地跳过测试

.. doctest:: [group]

doctest样式的代码块。您可以使用标准 doctest 标志来控制实际输出与输出结果的比较方式。默认标志集由 doctest_default_flags 配置变量指定。

选项

:hide:

在其他生成器中隐藏doctest块。默认情况下,它显示为突出显示的doctest块。

:options: doctest flags (comma separated list)

逗号分隔的doctest标志列表,适用于测试中的每个示例。(您仍然可以为每个示例提供显式标志,使用doctest注释,但它们也会出现在其他构建器中。)

或者,您可以像在doctest中一样给出内联doctest选项:

>>> datetime.date.now()
datetime.date(2008, 1, 1)

运行测试时将遵守它们,但默认情况下将从表示输出中删除。您可以使用选项 doctest:no-trim-doctest-flags 防止修剪。

:pyversion: (text)

指定要测试的示例所需的Python版本。例如,在以下情况下,只有对于大于3.14的Python版本才会测试该示例:

.. doctest::
   :pyversion: > 3.14

支持以下操作数:

  • ~=:兼容释放子句

  • =:版本匹配子句

  • !=:版本排除子句

  • <=>=:包含有序比较子句

  • <>:排他有序比较子句

  • ==:任意等式子句。

pyversion 选项后跟 PEP-440:版本说明符

在 1.6 版本加入.

在 1.7 版本发生变更: 支持的PEP-440操作数和符号

:trim-doctest-flags:
:no-trim-doctest-flags:

是否修剪删除行尾的doctest标志(类似 # doctest: FLAG,... 的注释)和单独的 <BLANKLINE> 标记。默认值为 trim-doctest-flags

注意,与标准doctest一样,您必须使用 <BLANKLINE> 在预期输出中发出空行信号。生成表示输出(HTML、LaTeX等)时,会删除 <BLANKLINE>

:skipif: condition (text)

如果python表达式 condition 为True,则跳过该指令。请参阅 有条件地跳过测试

.. testcode:: [group]

code-output-style测试的代码块。

选项

:hide:

在其他构建器中隐藏代码块。默认情况下,它显示为突出显示的代码块。

:trim-doctest-flags:
:no-trim-doctest-flags:

是否修剪删除行尾的doctest标志(类似 # doctest: FLAG,... 的注释)和单独的 <BLANKLINE> 标记。默认值为 trim-doctest-flags

:skipif: condition (text)

如果python表达式 condition 为True,则跳过该指令。请参阅 有条件地跳过测试

备注

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:

在其他生成器中隐藏doctest块。默认情况下,它显示为突出显示的doctest块。

:options: doctest flags (comma separated list)

逗号分隔的doctest标志列表。

:trim-doctest-flags:
:no-trim-doctest-flags:

是否修剪删除行尾的doctest标志(类似 # doctest: FLAG,... 的注释)和单独的 <BLANKLINE> 标记。默认值为 trim-doctest-flags

:skipif: condition (text)

如果python表达式 condition 为True,则跳过该指令。请参阅 有条件地跳过测试

例如:

.. testcode::

   print('Output     text.')

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

   Output text.

下面是指令用法的示例。测试通过 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,一个字符串选项,可用于有条件地跳过指令。这可能很有用,例如,根据环境(硬件、网络/VPN、可选依赖项或依赖项的不同版本)运行不同的测试集。所有doctest指令都支持 skipif 选项。以下是 skipif 在用于不同指令时的典型用例:

  • testsetuptestcleanup

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

    • 根据环境自定义安装/清理代码

  • doctest

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

  • testcode

    • 有条件地跳过测试

    • 每个自定义测试环境的代码

  • testoutput

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

    • 根据环境的不同预期不同的输出

将Python`的值计算为'skif`表达式。如果结果是真值,则从测试运行中忽略该指令,就像它根本不存在于文件中一样。

可以使用 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
类型:
int
默认:
ELLIPSIS | IGNORE_EXCEPTION_DETAIL | DONT_ACCEPT_TRUE_FOR_1

默认情况下,这些选项处于启用状态:

  • ELLIPSIS,允许您将省略号放在与实际输出中的任何内容匹配的预期输出中;

  • IGNORE_EXCEPTION_DETAIL,导致忽略最左边冒号后面的所有内容以及异常名称中的任何模块信息;

  • DONT_ACCEPT_TRUE_FOR_1 在输出时使用“1”而不是“TRUE”――这是python 2.2之前时代的默认行为。

在 1.5 版本加入.

doctest_show_successes
类型:
bool
默认:
True

控制是否报告成功。

对于有许多doctest的项目,将其设置为 False 以仅突出显示失败可能很有用。

在 7.2 版本加入.

doctest_path
类型:
Sequence[str]
默认:
()

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

doctest_global_setup
类型:
str
默认:
''

对于 每个 被测试的文件和每个组,它被当作放在 testsetup 指令中的Python代码。您可以使用它来导入您的doctest中始终需要的模块。

在 0.6 版本加入.

doctest_global_cleanup
类型:
str
默认:
''

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

在 1.1 版本加入.

doctest_test_doctest_blocks
类型:
str
默认:
'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 没有用特殊指令标记的扩展。

但是请注意,您不能在reStructuredText doctest块中有空行。它们将被解释为一个块结束和另一个块开始。此外,删除 <BLANKLINE># doctest: 选项仅适用于 doctest 块,尽管您可以设置 trim_doctest_flags 以在所有具有Python控制台内容的代码块中实现这一点。

doctest_fail_fast
类型:
bool
默认:
False

在遇到第一个失败时退出。

在 9.0 版本加入.