为什么 doctest 跳过对导入方法的测试?

Why is doctest skipping tests on imported methods?

我有一个 python 模块 some_module 和一个 __init__.py 导入方法的文件,如下所示:

from .some_python_file import some_method

some_method 有一个包含 doctests 的文档字符串:

def some_method():
    """
    >>> assert False
    """

但是当我在模块上 运行 doctest 时,即使测试失败,它也会通过。

import some_module
# How do I get this to consistently fail, regardless of whether
# `some_module.some_method` was declared inline or imported?
assert doctest.testmod(some_module).failed == 0

如果我改为在 __init__.py 文件中定义 some_method,doctest 正确地失败。

为什么这两种情况的表现不同?该方法存在并且在两种情况下具有相同的 __doc__ 属性。

如何让 doctest 运行 在导入模块的方法的 dostrings 中定义的测试?

在 Python 中,模块由单个文件定义,在您的情况下,some_python_file 是一个模块,而 __init__ 是另一个模块。 Doctest 只检查 运行 测试模块中可访问的示例,这些示例可以在 here.

中找到

在实践中查看此行为的最佳方法是在调用 doctest.testmod(some_module) 之前使用 PDBpdb.set_trace() 并进入内部以遵循逻辑。

乐: Doctest 根据 this comment. If you want to be able to run your test you should probably define a main function in your module and run the test test with python some_module.py. You can follow this example.

忽略导入的方法

要实现预期的行为,您需要在初始化文件中手动创建 __test__ 字典:

from .some_python_file import some_method

__test__ = {"some_method": some_method}

另见 this link

Objects imported into the module are not searched.

请参阅 which docstrings are examined 上的文档。

您可以将导入的函数注入到模块的 __test__ 属性中以测试导入的对象:

__test__ = {'some_method': some_method}

我偶然发现了这个问题,因为我正在破解一个导入对象的 __doc__ 属性。

from foo import bar
bar.__doc__ = """
>>> assert True
"""

and I was also wondering why the doctest of bar did not get executed by the doctest runner.

The previously given answer to add a `__test__` mapping solved it for good.

```python
__test__ = dict(bar=bar.__doc__)

我认为对此行为的解释如下。如果您使用的是库,比方说 NumPy,您不希望收集他们所有的 doctests 并 运行 在您自己的代码中。 很简单,因为它是多余的。 您应该相信库的开发人员会(持续)测试他们的代码,因此您不必这样做。

如果您在自己的代码中定义了测试,则应该有一个测试收集器(例如 pytest)进入项目结构的所有文件,运行 这些文件。 您最终会在使用过的库中测试所有文档测试,这会花费很多时间。所以忽略导入的doctests的决定是非常理智的。