Python doctests很酷。让我先从一个简单的例子开始:
def foo():
"""
>>> foo()
hello world
"""
print "hello world"
现在让我们假设某些部分有些变化,例如,因为它是时间值或随机数。通常,doctests允许我使用+ ELLIPSIS选项指定通配符。
当例如“world”是变化的字符串时,这可以正常工作:
def foo():
"""
>>> foo() # doctest: +ELLIPSIS
hello ...
"""
print "hello world"
但是,在我的情况下,变量字符串位于行的开头:
def foo():
"""
>>> foo() # doctest: +ELLIPSIS
... world
"""
print "hello world"
这很糟糕,因为开头的3个点被解释为行连续符,而不是输出的省略号。因此,此测试失败:
Failed example:
foo() # doctest: +ELLIPSIS
world
Expected nothing
Got:
hello world
所以,我现在可以重写我可以将变量部分放在其他地方,但有没有办法教doctest一行开头的3个点是省略号?
答案 0 :(得分:10)
这是一个快速而又脏的黑客:
def foo():
"""
>>> foo() # doctest: +ELLIPSIS
[...] world
"""
print "hello world"
if __name__ == "__main__":
import doctest
OC = doctest.OutputChecker
class AEOutputChecker(OC):
def check_output(self, want, got, optionflags):
from re import sub
if optionflags & doctest.ELLIPSIS:
want = sub(r'\[\.\.\.\]', '...', want)
return OC.check_output(self, want, got, optionflags)
doctest.OutputChecker = AEOutputChecker
doctest.testmod()
这仍然理解正常(...)省略号,但它增加了一个新的([...]),不会引起行开始歧义。
doctest很难猜测是否有一个行继续处于待处理状态,或者它是否一行开始省略号 - 理论上,如果你继承DocTestParser来完成这项工作,它可能会完成,但它可能不会乐趣。
在复杂的情况下,您应该推出自己的DocTestRunner,它将使用新的OutputChecker并使用它而不是普通的testmod,但这应该在简单的场景中完成。
答案 1 :(得分:5)
这是一种更简单的方法: 只需在以未知输出开头的行之前打印一个虚拟字符串。
像这样:
def foo():
"""
>>> print 'ignore'; foo() # doctest: +ELLIPSIS
ignore... world
"""
print "hello world"
答案 2 :(得分:5)
您可以为测试更新ELLIPSIS_MARKER
,以便...
不会与行续点混淆:
def foo():
"""
>>> import doctest
>>> doctest.ELLIPSIS_MARKER = '-ignore-'
>>> foo()
hello world
>>> foo() # doctest: +ELLIPSIS
-ignore- world
"""
print "hello world"
if __name__ == "__main__":
import doctest
doctest.testmod()
免责声明:上述示例在doctests作为
运行时有效$ py.test --doctest-module foo.py
或
$ python foo.py
但是,由于我不明白,在通过
运行doctests时它不起作用$ python -m doctest foo.py
答案 3 :(得分:2)
我最终解决了这个问题。
def foo():
"""
>>> foo() # doctest: +NORMALIZE_WHITESPACE, +ELLIPSIS
<BLANKLINE>
... world
"""
print("hello world")
至少在没有非空格字符或其他变通方法的情况下可以使用。
答案 4 :(得分:0)
如果您只是删除省略号后的尾随空格,这应该可以工作。
def foo():
"""
>>> foo() # doctest: +ELLIPSIS
...world
"""
print "hello world"