Python 是否有方法只执行doctest,而忽略打印函数调用?
假设地说,我的函数返回一个值,并且有很多打印语句(可能是100或更多) 是否有一种运行方式可以忽略/跳过所有其他打印工作(我熟悉Python 是否有方法只执行doctest,而忽略打印函数调用?,python,python-3.x,testing,doctest,Python,Python 3.x,Testing,Doctest,假设地说,我的函数返回一个值,并且有很多打印语句(可能是100或更多) 是否有一种运行方式可以忽略/跳过所有其他打印工作(我熟悉+SKIP指令,该指令用于跳过doctest示例),即当我使用doctests执行函数(或以脚本形式运行模块)时: python mymodule.py 或: 我应该得到: 如果成功,什么都没有;或 任何测试示例失败时的错误消息 没有别的了。运行doctest不会给我一个终端窗口,里面充满了那些print函数调用的输出/文本 请不要建议使用单元测试(例如),因为它
+SKIP
指令,该指令用于跳过doctest
示例),即当我使用doctest
s执行函数(或以脚本形式运行模块)时:
python mymodule.py
或:
我应该得到:
- 如果成功,什么都没有;或
- 任何测试示例失败时的错误消息李>
doctest
不会给我一个终端窗口,里面充满了那些print
函数调用的输出/文本
请不要建议使用单元测试(例如),因为它会扼杀问题的本质。
doctest
使用stdout
,而不是stderr
,来显示任何失败测试的消息。因此,您无法按照此答案最初的建议修补stdout
——这将禁止您的print
调用和doctest
中的任何消息
一个选项是使用附加的
verbose
参数定义打印
的函数,以便在必要时抑制此操作
def foo(verbose=True):
"""Does whatever.
>>> foo(verbose=False)
"""
if verbose:
print('Hello world')
尽管您必须更改函数,但在不进行测试时,这也为您提供了有用的选项
另一种方法是向使用它的函数显式提供适当的
print
函数,允许您在运行时传递NOOP:
def bar(print=print):
"""Does whatever.
>>> bar(print=lambda *args, **kwargs: None)
"""
print('Hello world')
这也需要更改函数定义,但至少可以避免更改这些函数的主体
第三个选项是为整个测试模块修补
打印,例如:
def baz():
"""Does whatever.
>>> baz()
"""
print('Hello world')
if __name__ == '__main__':
import doctest
print = lambda *args, **kwargs: None
doctest.testmod()
请注意,这也会影响doctest
看到的输出,因此您不会在docstring中包含任何print
输出(我认为这是个好消息!)它不会与python-m doctest mymodule.py一起工作,不过。除了“非常好的答案”,还有一种方法,这确实适用于python3-mdoctest module.py
构造
#!/usr/bin/python3 -OO
'''
Some ideas for adding additional verbosity during doctest, and for
reducing verbosity and startup delays during doctest or pydoc.
'''
from __future__ import print_function # for compatibility with python2
import sys, os, logging
logging.basicConfig(level = logging.DEBUG if __debug__ else logging.INFO)
COMMAND = os.path.splitext(os.path.basename(sys.argv[0]))[0]
if COMMAND in ['doctest', 'pydoc']:
NONDOCTESTPRINT = lambda *args, **kwargs: None
DOCTESTDEBUG = logging.debug
else:
NONDOCTESTPRINT = print
DOCTESTDEBUG = lambda *args, **kwargs: None
# You can also use this `else` block to import things not needed during
# doctest, especially slow-loading modules like `requests`,
# or to do some other verbose or slow initialization.
def test(string):
'''
print string after lead-in
>>> test("I'm in love with you!")
Listen!
I'm in love with you!
'''
DOCTESTDEBUG("If this works, you shouldn't see anything but this")
print('Listen!')
NONDOCTESTPRINT('Do you want to know a secret?')
NONDOCTESTPRINT('Do you promise not to tell? Whoa, oh...')
NONDOCTESTPRINT('Closer...')
NONDOCTESTPRINT('Let me whisper in your ear...')
NONDOCTESTPRINT('Say the words you long to hear...')
print(string)
if __name__ == '__main__':
test(' '.join(sys.argv[1:]) or 'Taxation is theft.')
下面是输出的外观,具体取决于调用方式
jcomeau@aspire:/tmp$ python3 -m doctest doctesttest.py
DEBUG:root:If this works, you shouldn't see anything but this
jcomeau@aspire:/tmp$ python3 doctesttest.py This is a test!
Listen!
Do you want to know a secret?
Do you promise not to tell? Whoa, oh...
Closer...
Let me whisper in your ear...
Say the words you long to hear...
This is a test!
对于pydoc doctest
:
非常好。对于最后一种情况,如何COMMAND=os.path.splitext(os.path.basename(sys.argv[0]))[0];打印=(lambda*args,**kwargs:None)如果命令==“doctest”else打印
@jcomeau_ictx我会保护重新分配,而不是使用三元表达式,但如果你需要edge case,这会起作用。是的,如果我不想在评论框中键入它,我也会这样做:微笑:'税收就是偷窃。'是政治,应该是流行歌曲或Monty Python引用。因为你一直在寻找被发现的机会。
jcomeau@aspire:/tmp$ python3 -m doctest doctesttest.py
DEBUG:root:If this works, you shouldn't see anything but this
jcomeau@aspire:/tmp$ python3 doctesttest.py This is a test!
Listen!
Do you want to know a secret?
Do you promise not to tell? Whoa, oh...
Closer...
Let me whisper in your ear...
Say the words you long to hear...
This is a test!