【发布时间】:2017-09-19 21:30:18
【问题描述】:
我的应用记录未处理的异常。
# app.py
import logging
import sys
logger = logging.getLogger(__name__)
def excepthook(exc_type, exc_value, traceback):
exc_info = exc_type, exc_value, traceback
if not issubclass(exc_type, (KeyboardInterrupt, SystemExit)):
logger.error('Unhandled exception', exc_info=exc_info)
sys.__excepthook__(*exc_info)
sys.excepthook = excepthook
def potato():
logger.warning('about to die...')
errorerrorerror
if __name__ == '__main__':
potato()
这些测试通过了:
# test_app.py
import app
import pytest
import sys
from logging import WARNING, ERROR
def test_potato_raises():
with pytest.raises(NameError):
app.potato()
def test_excepthook_is_set():
assert sys.excepthook is app.excepthook
# for caplog plugin: pip install pytest-catchlog
def test_excepthook_logs(caplog):
try:
whatever
except NameError as err:
exc_info = type(err), err, err.__traceback__
app.excepthook(*exc_info)
assert caplog.record_tuples == [('app', ERROR, 'Unhandled exception')]
[record] = caplog.records
assert record.exc_info == exc_info
但我无法测试未处理的异常日志记录是否正常工作:
def test_unhandled_exceptions_logged(caplog):
try:
app.potato()
finally:
assert caplog.record_tuples == [
('app', WARNING, 'about to die...'),
('app', ERROR, 'Unhandled exception'),
]
return # return eats exception
这里有什么问题?我们如何才能在测试中真正触发app.excepthook?
【问题讨论】:
-
“但我无法测试未处理的异常日志是否正常工作” - 好吧,直到异常真正传播到整个过程(它不会传播),它并不是真正的未处理异常,并且exceptionhook 不会触发。
-
对,这正是问题所在(测试运行程序捕获了异常)。我正在寻找一种方法来配置 pytest 以“让 [进一步] 让路”,即允许
app.excepthook运行,但不允许sys.__excepthook__运行。但也许这是不可能的。在子流程中运行是我希望避免的一种解决方法,因为目前尚不清楚如何让覆盖率报告在这种情况下协同工作。 -
看起来低级的
thread模块可能会让你这样做,虽然我不确定如何抑制“线程中未处理的异常由...启动”消息。跨度>
标签: python testing logging exception-handling pytest