doctest 中的第 continuation/wrapping 行

Line continuation/wrapping in doctest

我正在使用 doctest.testmod() 进行一些基本测试。我有一个函数 returns 一个长字符串,比如说 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: 这不是我正在使用的实际功能,而是为了您的需要而制作的最小版本。

来自 doctest 的文档:

如果您在交互式会话中通过反斜杠继续一行,或出于任何其他原因使用反斜杠,您应该使用原始文档字符串,这将在您键入它们时完全保留您的反斜杠:

>>> def f(x):
...     r'''Backslashes in a raw docstring: m\n'''
>>> print f.__doc__
Backslashes in a raw docstring: m\n

否则你可以使用双反斜杠。

一个简单的解决方案是>>> repr(get_string(1,2));这将转义新行并使用仅用于测试的单行字符串。

我更喜欢您可以说的解决方案:

>>> get_string(1,2)
first line
second line

fourth

在你的情况下,这是一个问题,因为你有尾随白色 space。

另请注意,无法测试行继续符。

"a" + \
"b"

完全一样
"a" + "b"

"ab"

我认为您不了解 doctest 的工作原理。它检查输出是否以某种方式"equivalent",它只检查输出是否相同(只有非常小的可能变化) ,就像使用省略号)。来自文档:

The doctest module searches for pieces of text that look like interactive Python sessions, and then executes those sessions to verify that they work exactly as shown.

Doctest 匹配 outputnot 字符串文字,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,您会发现不同的 hacks 使 doctests 更具可读性,同时提供可靠的输出。

如果您要针对输出中的长 single-line 字符串进行测试, 你可以将 doctest 匹配字符串保持在 80 个字符以内以获得 PEP8 善良 通过使用 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')

匹配的准确性略有下降,但这通常对测试来说并不重要。

您可以使用 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]