以下(废话)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)
会使读者偏离此。)
答案 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()