我正在使用doctest.testmod()
进行一些基本测试。我有一个函数返回一个长字符串,比如get_string()
。类似的东西:
def get_string(a, b):
r''' (a, b) -> c
>>> get_string(1, 2)
'This is \n\n a long \n string with new \
space characters \n\n'
# Doctest should work but does not.
'''
return ('This is \n\n a long \n string ' + \
'with new space characters \n\n')
问题是doctest没有通过,因为它期望单行字符串,并且它将包裹视为\n
字符。有办法解决这个问题吗?
PS:这不是我正在使用的实际功能,而是为您着想的最小版本。
答案 0 :(得分:6)
您可以使用NORMALIZE_WHITESPACE
选项(另请参阅full list of options)。
以下是doctest documentation的示例:
>>> print range(20) # doctest: +NORMALIZE_WHITESPACE
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
答案 1 :(得分:5)
我不认为你理解doctest
是如何运作的。它不检查输出是否以某种方式"等效",它只检查输出是否相同(只有非常小的可能变化,如使用省略)。来自文档:
doctest
模块搜索看起来像的文本片段 交互式Python会话,然后执行到的会话 验证它们完全如图所示。
Doctest将输出(不字符串文字,python表达式或其他任何内容。原始输出字节)与您提供的示例输出的内容进行匹配。由于它不知道引号之间的文本代表字符串文字,因此无法解释它。
换句话说:你唯一能做的就是简单地把整个输出放在一行上,如下所示:
>>> get_string(1, 2)
'This is \n\n a long \n string with new space characters \n\n'
如果此输出太长,您可以尝试修改示例以生成较短的字符串(例如,将其剪切为50
个字符:get_string(1, 2)[:50]
)。如果你看一下不同项目的doctests,你会发现不同的hack,使doctests在提供可靠输出的同时更具可读性。
答案 2 :(得分:3)
如果要对输出中的长单行字符串进行测试,
对于PEP8,你可以将doctest匹配字符串保持在80个字符以内
使用doctest的ELLIPSIS功能,其中...
将匹配任何字符串。
虽然它通常用于像对象地址这样的可变输出,
它也适用于(长)固定输出,例如:
def get_string(a, b):
r''' (a, b) -> c
>>> get_string(1, 2) # doctest: +ELLIPSIS
'This is ... string with newline characters \n\n'
'''
return ('This is \n\n a long \n string '
'with newline characters \n\n')
匹配中的精确度略有下降,但这通常对测试并不重要。
答案 3 :(得分:1)
来自doctest的文档:
如果您在交互式会话中通过反斜杠继续行,或者出于任何其他原因使用反斜杠,则应使用原始文档字符串,这将在您键入时完全保留反斜杠:
>>> def f(x):
... r'''Backslashes in a raw docstring: m\n'''
>>> print f.__doc__
Backslashes in a raw docstring: m\n
否则你可以使用双反斜杠。
答案 4 :(得分:1)
一个简单的解决方案是>>> repr(get_string(1,2))
;这将逃脱新行并使用单行字符串进行测试。
我更喜欢一个解决方案,你可以说:
>>> get_string(1,2)
first line
second line
fourth
在您的情况下,这是一个问题,因为您有尾随空格。
另请注意,无法测试续行符号。
"a" + \
"b"
与
完全相同"a" + "b"
即"ab"