sphinx.ext.doctest
– 文档中的代码片段测试¶
在文档中包含代码片段并演示其执行结果通常很有帮助。但重要的是要确保文档与代码保持最新。
此扩展允许您以自然的方式测试文档中的此类代码片段。如果您按照此处所示标记代码块,则 doctest
构建器将收集它们并将其作为 doctest 测试运行。
在每个文档中,您可以将每个代码片段分配给一个组。每个组包含
零个或多个设置代码块(例如,导入要测试的模块)
一个或多个测试块
使用 doctest
构建器构建文档时,将为每个文档收集组并按顺序运行,首先执行设置代码块,然后按其在文件中出现的顺序执行测试块。
有两种类型的测试块
doctest 样式块通过交错 Python 代码(包括解释器提示)和输出,模拟交互式会话。
代码-输出样式块由一段普通的 Python 代码组成,以及可选的该代码的输出。
指令¶
下面的group 参数解释如下:如果为空,则将块分配给名为 default
的组。如果为 *
,则将块分配给所有组(包括 default
组)。否则,它必须是组名称的逗号分隔列表。
- .. testsetup:: [group]¶
设置代码块。此代码不会在其他构建器的输出中显示,但在其所属组的 doctest 之前执行。
- .. testcleanup:: [group]¶
清理代码块。此代码不会在其他构建器的输出中显示,但在其所属组的 doctest 之后执行。
版本 1.1 中新增。
- .. doctest:: [group]¶
doctest 样式的代码块。您可以使用标准
doctest
标志来控制如何将实际输出与您提供的输出进行比较。标志的默认集由doctest_default_flags
配置变量指定。此指令支持五个选项
hide
,一个标志选项,隐藏其他构建器中的 doctest 块。默认情况下,它显示为突出显示的 doctest 块。options
,一个字符串选项,可用于提供应用于测试中每个示例的 doctest 标志的逗号分隔列表。(您仍然可以在每个示例中提供显式标志,使用 doctest 注释,但它们也会显示在其他构建器中。)pyversion
,一个字符串选项,可用于指定要测试的示例所需的 Python 版本。例如,在以下情况下,仅对大于 3.12 的 Python 版本测试示例.. doctest:: :pyversion: > 3.12
支持以下操作数
~=
:兼容版本声明==
:版本匹配声明!=
:版本排除声明<=
、>=
:包含有序比较声明<
、>
:排除非有序比较声明===
:任意相等声明。
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>
。此外,您还可以提供内联 doctest 选项,就像在 doctest 中一样
>>> datetime.date.now() # doctest: +SKIP datetime.date(2008, 1, 1)
运行测试时将尊重它们,但会从演示输出中删除。
- .. testcode:: [group]¶
代码-输出样式测试的代码块。
此指令支持三个选项
hide
,一个标志选项,隐藏其他构建器中的代码块。默认情况下,它显示为突出显示的代码块。trim-doctest-flags
和no-trim-doctest-flags
,一个标志选项,doctest 标志(类似于# doctest: FLAG, ...
的注释)在行尾和<BLANKLINE>
标记将被单独删除(或不删除)。默认值为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
,一个标志选项,隐藏其他构建器中的输出块。默认情况下,它显示为没有突出显示的文字块。options
,一个字符串选项,可用于提供 doctest 标志(逗号分隔),就像在普通 doctest 块中一样。trim-doctest-flags
和no-trim-doctest-flags
,一个标志选项,doctest 标志(类似于# doctest: FLAG, ...
的注释)在行尾和<BLANKLINE>
标记将被单独删除(或不删除)。默认值为trim-doctest-flags
。
示例
.. testcode:: print('Output text.') .. testoutput:: :hide: :options: -ELLIPSIS, +NORMALIZE_WHITESPACE Output text.
以下是指令用法的示例。通过 doctest
进行的测试与通过 testcode
和 testoutput
进行的测试是等价的。
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、可选依赖项或依赖项的不同版本)运行不同的测试集时,这可能很有用。skipif
选项受所有 doctest 指令支持。以下是使用不同指令时 skipif
的典型用例
-
有条件地跳过测试设置和/或清理
根据环境自定义设置/清理代码
-
有条件地跳过测试及其输出验证
-
有条件地跳过测试
根据环境自定义测试代码
-
有条件地跳过已跳过测试的输出断言
根据环境预期不同的输出
skipif
选项的值将作为 Python 表达式进行评估。如果结果为真值,则指令将从测试运行中省略,就像它根本不存在于文件中一样。
无需重复表达式,可以使用 doctest_global_setup
配置选项将其赋值给一个变量,然后可以使用该变量。
以下是一个示例,如果未安装 Pandas,则跳过某些测试
extensions = ['sphinx.ext.doctest']
doctest_global_setup = '''
try:
import pandas as pd
except ImportError:
pd = None
'''
.. 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
,允许您在预期输出中放置省略号,以匹配实际输出中的任何内容;IGNORE_EXCEPTION_DETAIL
,导致忽略异常名称中左侧最靠近冒号的所有内容以及任何模块信息;DONT_ACCEPT_TRUE_FOR_1
,拒绝输出中出现“True”的情况,而“1”则被接受——接受这种替换的默认行为是 Python 2.2 之前的遗留行为。
版本 1.5 中新增。
- doctest_show_successes¶
默认为
True
。控制是否报告成功。对于包含许多 doctest 的项目,将其设置为
False
可能很有用,以便仅突出显示失败。版本 7.2 中新增。
- doctest_global_setup¶
Python 代码,其处理方式如同放置在每个要测试的文件和每个组的
testsetup
指令中一样。您可以使用它来导入 doctest 中始终需要的模块。版本 0.6 中新增。
- doctest_global_cleanup¶
Python 代码,其处理方式如同放置在每个要测试的文件和每个组的
testcleanup
指令中一样。您可以使用它来删除测试留下的任何临时文件。版本 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
扩展中的文档字符串中的 doctest,而无需使用特殊指令进行标记。但请注意,您不能在 reStructuredText doctest 块中包含空行。它们将被解释为一个块结束,另一个块开始。此外,仅在
doctest
块中才能删除<BLANKLINE>
和# doctest:
选项,尽管您可以在所有包含 Python 控制台内容的代码块中设置trim_doctest_flags
以实现这一点。