test11.py
import logging
from functools import wraps
def log_exceptions(func):
@wraps(func)
def wrapper(*args, **kwargs):
# 创建日志记录器
logger = logging.getLogger(func.__name__)
logger.setLevel(logging.ERROR)
# 创建文件处理器
file_handler = logging.FileHandler('error.log')
file_handler.setLevel(logging.ERROR)
# 创建日志格式器
formatter = logging.Formatter('%(asctime)s | %(filename)s | line:%(lineno)d | %(levelname)s | %(message)s')
file_handler.setFormatter(formatter)
# 将文件处理器添加到日志记录器
logger.addHandler(file_handler)
try:
return func(*args, **kwargs)
except Exception as e:
# 捕获异常并记录日志
logger.error('An error occurred: %s', str(e))
raise # 重新抛出异常,保持异常的传递性
return wrapper
这段代码定义了一个装饰器函数log_exceptions
,用于捕获函数执行过程中的异常并记录到日志文件中。
代码的解析如下:
- 导入了
logging
模块和wraps
函数。 - 定义了
log_exceptions
装饰器函数,接受一个函数作为参数。 - 在装饰器函数内部定义了一个内部函数
wrapper
,用于包装原始函数。 - 在
wrapper
函数内部创建了一个日志记录器对象,并设置日志级别为ERROR
。 - 创建了一个文件处理器对象,用于将日志写入到名为
error.log
的文件中,并设置日志级别为ERROR
。 - 创建了一个日志格式器对象,定义了日志的格式,包括时间、文件名、行号、日志级别和消息内容。
- 将文件处理器添加到日志记录器中。
- 使用
try-except
块包裹原始函数的执行过程。 - 如果原始函数执行过程中发生异常,捕获异常并记录到日志中。
- 重新抛出异常,保持异常的传递性。
- 返回包装后的函数
wrapper
。
通过使用log_exceptions
装饰器,可以将其应用于需要捕获异常并记录到日志的函数上,以便在出现异常时进行日志记录和异常处理。
test22.py
import pytest
from test11 import log_exceptions
@log_exceptions
def test_divide():
assert 1 == 2
@log_exceptions
def test_divide2():
assert 1 == '14'
def test_divide3():
assert 1 == 1
if __name__ == '__main__':
pytest.main(["-s", "test22.py"])
这段代码使用了之前定义的装饰器函数log_exceptions
来装饰测试函数,并使用pytest
库运行测试脚本。
代码的主要部分包括三个测试函数:test_divide()
,test_divide2()
和test_divide3()
。
test_divide()
函数断言1等于2,这是一个错误的断言,会引发AssertionError
异常。由于该函数被log_exceptions
装饰器装饰,当异常发生时,装饰器会捕获异常并记录到日志文件中。
test_divide2()
函数断言1等于字符串'14',这也是一个错误的断言,会引发AssertionError
异常。同样地,由于该函数被log_exceptions
装饰器装饰,异常会被捕获并记录到日志文件中。
test_divide3()
函数断言1等于1,这是一个正确的断言,不会引发异常。
最后,通过pytest.main(["-s", "test22.py"])
运行了测试脚本,并使用-s
参数来显示打印信息。
通过使用log_exceptions
装饰器,可以捕获测试函数执行过程中的异常,并将异常信息记录到日志文件中,以便后续查看和分析。