【问题标题】:How to check that print was called in a function?如何检查 print 是否在函数中被调用?
【发布时间】:2020-06-13 13:08:23
【问题描述】:

假设f有条件地调用print;我想知道这是否发生在test_*() 内。这如何实现?


示例

def f(integer):  # defined in and imported from separate module
    if isinstance(integer, str):
        print("WARNING: integer is str")

def test_f():
    f("5")
    assert print.called

尝试的方法

def tracked_call(self, *args, **kwargs):
    self.called = True
    self.__call__(*args, **kwargs)

print.__call__ = tracked_call
>>> AttributeError: 'builtin_function_or_method' object attribute '__call__' is read-only

【问题讨论】:

标签: python python-3.x pytest python-unittest


【解决方案1】:

解决方案 1(最佳):检查 print 是否被调用,并且它是否打印特定文本;不使用夹具:

import builtins
import contextlib, io
from unittest.mock import Mock

def test_f():
    mock = Mock()
    mock.side_effect = print  # ensure actual print is called to capture its txt
    print_original = print
    builtins.print = mock

    try:
        str_io = io.StringIO()
        with contextlib.redirect_stdout(str_io):
            f("5")
        output = str_io.getvalue()

        assert print.called  # `called` is a Mock attribute
        assert output.startswith("WARNING:")
    finally:
        builtins.print = print_original  # ensure print is "unmocked"

(如果f 中的print 写入sys.stderr 而不是默认的sys.stdout,则使用contextlib.redirect_stderr。)


解决方案 2:检查 print 是否在调用中打印特定文本;来自docs

def test_f(capsys):
    f("5")
    out, err = capsys.readouterr()
    assert out.startswith("WARNING:")

这假设默认print(file=sys.stdout),否则感兴趣的字符串在err。如果对特定文本不感兴趣,可以通过 assert out or err 验证是否打印了 something。这并不一定测试print 是否被调用,我们可以测试print(end='')

【讨论】:

    猜你喜欢
    • 2011-09-08
    • 1970-01-01
    • 2020-05-31
    • 1970-01-01
    • 1970-01-01
    • 2013-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多