有没有办法只执行doctests,忽略打印函数调用?

Nab*_*med 2 python testing doctest python-3.x

假设,我的函数返回一个值并且有很多print语句(可能是100或更多).

有没有办法运行doctest,以便可以忽略/跳过所有其他打印工作(我熟悉该+SKIP指令,用于跳过doctest示例),即当我执行我的函数(或运行我的模块作为脚本)与doctests :

python mymodule.py
Run Code Online (Sandbox Code Playgroud)

要么:

python -m doctest mymodule.py
Run Code Online (Sandbox Code Playgroud)

我应该得到:

  • 没有,如果成功; 要么
  • 任何测试示例失败的错误消息;

没有别的.运行doctest不应该给我一个充满这些print函数调用的输出/文本的终端窗口.

请不要建议使用单元测试(例如unittest)因为它会杀死问题的本质.

jon*_*rpe 5

doctest用途stdout, stderr,显示来自任何测试失败的消息.因此,您无法修补stdout此答案最初建议 - 这将抑制您的print来电来自的任何消息doctest.


一种选择是print使用附加verbose参数定义函数,以便在必要时可以抑制此函数.

def foo(verbose=True):
    """Does whatever.

        >>> foo(verbose=False)

    """
    if verbose:
        print('Hello world')
Run Code Online (Sandbox Code Playgroud)

虽然您必须更改功能,但这也为您提供了不测试时的有用选项.


另一个是显式地print为使用它的函数提供适当的函数,允许您在运行时传递NOOP:

def bar(print=print):
    """Does whatever.

        >>> bar(print=lambda *args, **kwargs: None)

    """
    print('Hello world')
Run Code Online (Sandbox Code Playgroud)

这也需要更改函数定义,但至少要避免更改这些函数的主体.


第三种选择是print为整个待测模块进行补丁,例如:

def baz():
    """Does whatever.

        >>> baz()

    """
    print('Hello world')

if __name__ == '__main__':

    import doctest

    print = lambda *args, **kwargs: None

    doctest.testmod()
Run Code Online (Sandbox Code Playgroud)

请注意,这doctest也会影响所看到的输出,因此您不会print在docstring中包含任何输出(我认为这是个好消息!)但它不适用python -m doctest mymodule.py.