我可以在Python doctest的行首加上省略号吗?

问题描述 投票:15回答:4

Python doctest很酷。让我从一个简单的例子开始:

def foo():
  """
  >>> foo()
  hello world
  """
  print "hello world"

现在,假设某些部分有所变化,例如,因为它是时间值或随机数。通常,doctest允许我使用+ 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

因此,我现在可以重写我的代码,以使变量部分位于其他位置,但是有什么方法可以教文档测试该行开头的三个点是省略号吗?

python doctest
4个回答
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,但是在简单的情况下应该这样做。


6
投票

您可以为测试更新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()

Disclaimer:当doctests以

运行时,以上示例适用
$ py.test --doctest-module foo.py

$ python foo.py

但是,由于我不明白的原因,通过以下方式运行doctest时,它不起作用:>

$ python -m doctest foo.py

5
投票

这里是一种较为简单的方法:只需在以未知输出开头的行之前打印一个虚拟字符串即可。


0
投票

我最终解决了这个问题。

© www.soinside.com 2019 - 2024. All rights reserved.