Doctests:如何抑制/忽略输出?

时间:2010-10-05 09:12:28

标签: python doctest

以下(废话)Python模块的doctest失败:

"""
>>> 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的副作用。那么如何抑制输出或如何忽略它。我尝试过:

"""
>>> 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)会使读者偏离此。)

2 个答案:

答案 0 :(得分:5)

重写:这实际上现在可以正常工作;我意识到我之前写的“doctest”实际上并没有被解析为模块docstring,所以测试没有通过:它只是没有被运行。

我确保仔细检查一下。

__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...>)。 ELLIPSIS选项使...“匹配实际输出中的任何子串¹。所以我认为没有办法让它与整个输出相匹配。

更新:要以“正确”方式执行此操作,您似乎想要调用doctest.register_optionflag('IGNORE_RESULT'),子类doctest.OptionChecker并安排该实例doctest使用的子类。据推测,这意味着通过$ python -m doctest your_module.py运行doctest不是一种选择。

答案 1 :(得分:0)

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

我不知道这是一个干净的解决方案,我之前已经打过它;它似乎是doctests提供的模糊(更直率:草率)测试定义的副作用。解决方法是记住您可以在doctests中定义函数,这样您就可以将整个测试作为单个函数而不是单个函数包含在内。

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()