首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Doctest:如何抑制/忽略输出?

Doctest:如何抑制/忽略输出?
EN

Stack Overflow用户
提问于 2010-10-05 17:12:28
回答 3查看 3.6K关注 0票数 4

以下(无意义的) Python模块的doctest失败:

代码语言:javascript
复制
"""
>>> L = []
>>> if True:
...    append_to(L) # XXX
>>> L
[1]
"""

def append_to(L):
    L.append(1)
    class A(object):
        pass
    return A()

import doctest; doctest.testmod()

这是因为标记为XXX的行后的输出是<__main__.A object at ...> (由append_to返回)。当然,我可以将此输出直接放在标记为XXX的行后面,但在我的例子中,这会分散读者对实际测试内容的注意力,即函数append_to的副作用。那么,我如何抑制该输出,或者如何忽略它。我试了一下:

代码语言:javascript
复制
"""
>>> L = []
>>> if True:
...    append_to(L) # doctest: +ELLIPSIS
    ...
>>> L
[1]
"""

def append_to(L):
    L.append(1)
    class A(object):
        pass
    return A()

import doctest; doctest.testmod()

但是,这会产生一个ValueError: line 4 of the docstring for __main__ has inconsistent leading whitespace: ' ...'

我不想做的是将append_to(L)行更改为类似_ = append_to(L)的内容,这样会抑制输出,因为doctest用于文档目的,并向读者显示应该如何使用模块。(在记录的情况下,append_to应该像语句一样使用,而不是像函数一样使用。编写_ = append_to(L)会使读者偏离这一点。)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-10-05 18:35:54

重写:它现在确实起作用了;我意识到我之前编写的"doctest“实际上没有被解析为模块文档字符串,所以测试没有通过:它只是没有运行。

我确保仔细检查了这一次。

代码语言:javascript
复制
__doc__ = """
>>> L = []
>>> if True:
...    append_to(L) # doctest: +IGNORE_RESULT
>>> L
[1]
""".replace('+IGNORE_RESULT', '+ELLIPSIS\n<...>')

def append_to(L):
    L.append(1)
    class A(object):
        pass
    return A()

我不确定这是不是更具可读性。请注意,<...>没有什么特别之处:只有当实际返回值具有这种形式时,它才会工作,就像本例中的形式一样(即它是<module.A object at 0x...>)。省略号选项使...“匹配实际输出中的任何子串¹。所以我不认为有一种方法可以让它与整个输出匹配。

更新:要以“正确”的方式做到这一点,看起来您需要调用doctest.register_optionflag('IGNORE_RESULT'),子类doctest.OptionChecker,并安排该子类的一个实例供doctest使用。这可能意味着不能通过$ python -m doctest your_module.py运行文档测试。

票数 7
EN

Stack Overflow用户

发布于 2021-10-30 17:15:41

我之所以要问这个问题,是因为我需要+IGNORE_RESULT行为,而不是为了在sphinx文档上运行文档测试。@intuited发布的replace答案在这种情况下不起作用,并且没有用于所提到的“适当”解决方案的代码。因此,我发布了我最终得到的东西。

作为对这个问题的直接回答,解决方案是:

代码语言:javascript
复制
__doc__ = """
>>> L = []
>>> if True:
...    append_to(L) # doctest: +IGNORE_RESULT
>>> L
[1]
"""

def append_to(L):
    L.append(1)
    class A(object):
        pass
    return A()

if __name__ == "__main__":
    import doctest

    IGNORE_RESULT = doctest.register_optionflag('IGNORE_RESULT')

    OutputChecker = doctest.OutputChecker
    class CustomOutputChecker(OutputChecker):
        def check_output(self, want, got, optionflags):
            if IGNORE_RESULT & optionflags:
                return True
            return OutputChecker.check_output(self, want, got, optionflags)

    doctest.OutputChecker = CustomOutputChecker
    doctest.testmod()

为了满足我对文档测试sphinx文档的特殊需求,将其添加到conf.py文件中:

代码语言:javascript
复制
import doctest

IGNORE_RESULT = doctest.register_optionflag('IGNORE_RESULT')

OutputChecker = doctest.OutputChecker
class CustomOutputChecker(OutputChecker):
    def check_output(self, want, got, optionflags):
        if IGNORE_RESULT & optionflags:
            return True
        return OutputChecker.check_output(self, want, got, optionflags)

doctest.OutputChecker = CustomOutputChecker

然后使用如下命令进行测试:

代码语言:javascript
复制
sphinx-build -M doctest source_dir build_dir source_dir/file.rst
票数 0
EN

Stack Overflow用户

发布于 2010-10-05 17:47:03

请尝试提供完全自包含的、可运行的代码;即使在演示问题时,代码也应该自己运行以重现问题,以便解决方案可以直接复制代码以演示答案。

我不知道有一个干净的解决方案来解决这个问题,我以前也遇到过;这似乎是doctest提供的模糊(更直白地说是草率的)测试定义的副作用。一种解决方法是记住,您可以在doctest中定义函数,这样您就可以将整个测试包含为单个函数,而不是其单独的语句。

代码语言:javascript
复制
def append_to(l):
    """
    >>> L = []
    >>> def test():
    ...     if True:
    ...         append_to(L) # XXX
    >>> test()
    >>> L
    [1]

    >>> def test():
    ...     L = []
    ...     if True:
    ...         append_to(L) # XXX
    ...     return L
    >>> test()
    [1]

    """
    l.append(1)
    return object()

if __name__ == "__main__":
    import doctest
    doctest.testmod()
票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3862274

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档