Python doctest能忽略某些输出行吗?

43 投票
7 回答
15028 浏览
提问于 2025-04-15 12:24

我想写一个像这样的文档测试:

"""
>>> print a.string()
          foo : a
          bar : b
         date : <I don't care about the date output>
          baz : c
"""

有没有办法做到这一点?我觉得换成unittest会更合适,但我很好奇在文档测试中是否可以指定一段输出不需要匹配测试结果。

谢谢!

7 个回答

15

我发现把那些不需要的返回值直接赋值给一个变量更简单:

>>> _ = do_something()
>>> check_something()
True
20

关于“我们怎么能忽略整行”的问题,确实,"..."看起来像是继续的内容,这让我们很难忽略整个输出。如果你只是想完全跳过这个例子,可以用"#doctest: +SKIP",但如果你依赖它的副作用,这个方法就不太管用了。如果你真的需要这样做,我想你可以尝试修改doctest模块本身,不过我不太推荐这样做:

>>> import doctest
>>> doctest.ELLIPSIS_MARKER = '-etc-'
>>> print 12 # doctest: +ELLIPSIS
-etc-

(这个测试通过了。)

或者你可以暂时屏蔽标准输出和错误输出:

>>> # Suppress stdout
>>> import sys
>>> class DevNull:
...     def noop(*args, **kwargs): pass
...     close = write = flush = writelines = noop
>>> sys.stdout = DevNull()
>>> # Run a test and ignore output (but we need its side effects)
>>> print 12 # NOTE: stdout is suppressed!
>>> # Restore stdout
>>> sys.stdout = sys.__stdout__

(这个测试也通过了。)

50

使用 doctest.ELLIPSIS,你可以用 ... 来表示“这里可以匹配任何字符串”。你可以通过一个 doctest 指令来设置 doctest 的选项,这样它只对一个测试案例生效:在在线文档中有一个例子:

>>> print range(20) # doctest:+ELLIPSIS
[0, 1, ..., 18, 19]

如果你想让某个 doctest 选项在整个测试中都有效,可以把它作为 optionflags= 参数传递给你使用的任何 doctest 函数,比如 doctest.testfile。你还可以通过使用 | 运算符将多个选项组合在一起。

撰写回答