模块和测试文件的Doctest集成¶
默认情况下,所有匹配 test*.txt
模式将通过python标准运行 doctest
模块。您可以通过发出以下命令来更改模式:
pytest --doctest-glob="*.rst"
在命令行上。 --doctest-glob
可以在命令行中多次给定。
如果您有这样的文本文件:
# content of test_example.txt
hello this is a doctest
>>> x = 3
>>> x
3
然后你就可以调用 pytest
直接:
$ pytest
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-6.x.y, py-1.x.y, pluggy-0.x.y
cachedir: $PYTHON_PREFIX/.pytest_cache
rootdir: $REGENDOC_TMPDIR
collected 1 item
test_example.txt . [100%]
============================ 1 passed in 0.12s =============================
默认情况下,pytest将收集 test*.txt
文件正在查找doctest指令,但您可以使用 --doctest-glob
选项(允许多个)。
除了文本文件之外,您还可以直接从类和函数的docstrings(包括测试模块)执行doctest:
# content of mymodule.py
def something():
"""a doctest in a docstring
>>> something()
42
"""
return 42
$ pytest --doctest-modules
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-6.x.y, py-1.x.y, pluggy-0.x.y
cachedir: $PYTHON_PREFIX/.pytest_cache
rootdir: $REGENDOC_TMPDIR
collected 2 items
mymodule.py . [ 50%]
test_example.txt . [100%]
============================ 2 passed in 0.12s =============================
通过将这些更改放入pytest.ini文件,可以在项目中永久性地进行这些更改,如下所示:
# content of pytest.ini
[pytest]
addopts = --doctest-modules
编码¶
默认编码是 UTF-8 ,但可以使用 doctest_encoding
ini选项:
# content of pytest.ini
[pytest]
doctest_encoding = latin1
使用“doctest”选项¶
Python 标准 doctest
module provides some options 配置doctest测试的严格性。在pytest中,可以使用配置文件启用这些标志。
例如,要使pytest忽略尾随空格并忽略冗长的异常堆栈跟踪,您只需编写:
[pytest]
doctest_optionflags = NORMALIZE_WHITESPACE IGNORE_EXCEPTION_DETAIL
或者,可以通过文档测试本身中的内联注释启用选项:
>>> something_that_raises() # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
ValueError: ...
pytest还引入了新的选项:
ALLOW_UNICODE
:启用后,u
在预期的doctest输出中,前缀从unicode字符串中剥离。这使得doctest可以在python2和python3中运行。ALLOW_BYTES
:类似地b
前缀将从预期doctest输出中的字节字符串中剥离。NUMBER
:启用时,浮点数只需与在预期doctest输出中写入的精度匹配。例如,以下输出只需要匹配2个小数位:>>> math.pi 3.14
如果你写信
3.1416
那么实际输出需要匹配到小数点后4位,依此类推。这样可以避免由于浮点精度有限而导致的误报,例如:
Expected: 0.233 Got: 0.23300000000000001
NUMBER
还支持浮点数的列表——事实上,它匹配出现在输出中任何地方的浮点数,即使是在字符串中!这意味着在全局范围内启用doctest_optionflags
在配置文件中。5.1 新版功能.
失败时继续¶
默认情况下,pytest将只报告给定doctest的第一个失败。如果要继续测试,即使出现故障,也要执行以下操作:
pytest --doctest-modules --doctest-continue-on-failure
输出格式¶
在选项中使用标准doctest模块格式之一,可以在doctest失败时更改doctest的diff输出格式(请参见 doctest.REPORT_UDIFF
, doctest.REPORT_CDIFF
, doctest.REPORT_NDIFF
, 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
Pytest特定功能¶
提供了一些功能,可以使编写doctest更容易,或者与现有测试套件更好地集成。但是请记住,通过使用这些特性,您的教义将与标准不兼容。 doctests
模块。
使用固定装置¶
可以使用固定装置 getfixture
帮手:
# content of example.rst
>>> tmp = getfixture('tmpdir')
>>> ...
>>>
注意,fixture需要在pytest可见的地方定义,例如 conftest.py
文件或插件;包含docstring的普通python文件通常不会扫描fixture,除非由 python_files
.
此外, usefixtures 标记和固定装置标记为 autouse 在执行文本doctest文件时支持。
'doctest_namespace'夹具¶
这个 doctest_namespace
fixture可用于将项注入到运行doctest的命名空间中。它旨在在您自己的设备中使用,以提供将它们与上下文一起使用的测试。
doctest_namespace
是一个标准 dict
对象,将要在doctest命名空间中显示的对象放入其中:
# content of conftest.py
import numpy
@pytest.fixture(autouse=True)
def add_np(doctest_namespace):
doctest_namespace["np"] = numpy
然后可以直接用于您的医生:
# content of numpy.py
def arange():
"""
>>> a = np.arange(10)
>>> len(a)
10
"""
pass
注意,和正常情况一样 conftest.py
,在目录树conftest所在的目录中找到这些设备。也就是说,如果将doctest与源代码放在一起,那么相关的conftest.py必须位于同一目录树中。在同级目录树中不会发现设备!
跳过测试¶
出于同样的原因,人们可能想要跳过普通测试,也可以跳过doctest中的测试。
要跳过doctest中的单个检查,可以使用标准 doctest.SKIP 指令:
def test_random(y):
"""
>>> random.random() # doctest: +SKIP
0.156231223
>>> 1 + 1
2
"""
这将跳过第一次检查,但不会跳过第二次。
pytest还允许使用标准pytest函数 pytest.skip()
和 pytest.xfail()
在doctest内部,这可能很有用,因为您可以根据外部条件跳过/xFAIL测试:
>>> import sys, pytest
>>> if sys.platform.startswith('win'):
... pytest.skip('this doctest does not work on Windows')
...
>>> import fcntl
>>> ...
但是,不鼓励使用这些函数,因为它降低了文档字符串的可读性。
注解
pytest.skip()
和 pytest.xfail()
根据doctest是在Python文件(在docstring中)还是在包含混合了文本的doctest的文本文件中,行为会有所不同:
Python模块(文档字符串):函数只作用于该特定文档字符串,让同一模块中的其他文档字符串正常执行。
文本文件:函数跳过/x检查整个文件的睡觉。
选择¶
虽然内置的pytest支持为使用doctest提供了一组很好的功能,但是如果您广泛使用它们,您可能会对那些添加了更多功能并包括pytest集成的外部包感兴趣:
pytest-doctestplus :提供高级文档测试支持,并启用reStruredText(“.rst”)文件的测试。
Sybil :提供一种测试文档中的示例的方法,方法是从文档源解析它们,并将分析的示例作为正常测试运行的一部分进行计算。