【问题标题】:How to write a unit test for uncaught exception handler如何为未捕获的异常处理程序编写单元测试
【发布时间】:2019-04-25 06:25:44
【问题描述】:

我有一个捕捉未捕获异常的函数,如下所示。有没有办法写一个单元测试,执行uncaught_exception_handler()函数,但正常退出测试?

import logging

def config_logger():
    # logger setup here

def init_uncaught_exception_logger(logger):
    '''Setup an exception handler to log uncaught exceptions.

    This is typically called once per main executable.
    This function only exists to provide a logger context to the nested function.

    Args:
        logger (Logger): The logger object to log uncaught exceptions with.
    '''
    def uncaught_exception_handler(*exc_args):
        '''Log uncaught exceptions with logger.

        Args:
            exc_args: exception type, value, and traceback
        '''
        print("Triggered uncaught_exception_handler")
        logger.error("uncaught: {}: {}\n{}".format(*exc_args))

    sys.excepthook = uncaught_exception_handler

if __name__ == '__main__':
    LOGGER = config_logger()
    init_uncaught_exception_logger(LOGGER)
    raise Exception("This is an intentional uncaught exception")

【问题讨论】:

标签: python unit-testing exception


【解决方案1】:

与其测试您的函数是否因未捕获的异常而被调用,不如测试excepthook 是否已安装,并且当您手动调用该函数时该函数是否正确。这为您提供了很好的证据,证明excepthook 在实际使用中会正常运行。您需要将 uncaught_exception_handler 移到 init_uncaught_exception_logger 之外,以便您的测试可以更轻松地访问它。

assert sys.excepthook is uncaught_exception_handler
with your_preferred_output_capture_mechanism:
    try:
        1/0
    except ZeroDivisionError:
        uncaught_exception_handler(*sys.exc_info())
assert_something_about_captured_output()

如果您想通过未捕获的异常实际调用excepthook,那么您需要启动一个子进程并检查其输出。 subprocess module 是实现这一目标的方法。

【讨论】:

  • 感谢@user2357112,为我解决了这个问题和我的心理障碍。
【解决方案2】:

为了编写有关引发异常的断言,您可以使用pytest.raises 作为上下文管理器,如下所示:

with raises(expected_exception: Exception[, match][, message])

import pytest

def test_which_will_raise_exception():
    with pytest.raises(Exception):
        # Your function to test.

现在,只有在 pytest.raises 上下文管理器下的任何代码将引发作为参数提供的异常时,此单元测试才会通过。在这种情况下,它是Exception

【讨论】:

  • 参见sys.excepthook,具体来说:“当引发异常并且未捕获时,解释器调用 sys.excepthook...”。 pytest.raises() 是否捕捉到sys.excepthook 之后的异常?
  • @QuantumMechanic 如果调用来自pytest.raises 上下文管理器中的测试代码,那么它应该。给我一些时间,我会做一些研究和测试。如果这可行,那么我将提供一个更详细的示例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-16
  • 2021-10-17
  • 1970-01-01
  • 1970-01-01
  • 2014-09-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多