一、日志类封装
from io import StringIO import sys import os from loguru import logger sys.path.append((os.path.abspath(os.path.join(os.path.dirname(__file__), '../')))) project_path = os.path.dirname(os.path.join(os.path.dirname(__file__))) log_path = os.path.join(project_path, r'common\logger_info')class Logconfig:def __init__(self, log_file_dir='logger_info',log_name='case_log_info.log',level='DEBUG',rotation="10 MB", retention="7 days"):"""log日志封装:param log_file_dir: 日志路径:param log_name: 日志名称:param level: 日志输出等级:param rotation: 日志保存大小:param retention: 日志保存时间"""# 创建日志输出路径self.log_file_dir = log_file_dirif not os.path.exists(self.log_file_dir):os.makedirs(self.log_file_dir)# 配置日志self.level = levelself.rotation = rotationself.retention = retention# 配置日志写入文件路径self.log_file_dir = os.path.join(self.log_file_dir, log_name)print('日志写入路径:',self.log_file_dir)# 创建一个缓冲区用于捕获日志self.log_capture = StringIO()# 调用日志配置方法self.logconfig()def logconfig(self):# 清除默认配置logger.remove()# 配置日志输出到控制台logger.add(sink=sys.stdout,format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level: <8}</level> |{module}.{function}() at line {line}-{message}",level=self.level)# 配置日志输出到文件logger.add(sink=self.log_file_dir,format = "{time:YYYY-MM-DD HH:mm:ss} |{level: <8} | {module}.{function}() at line {line}-{message}",level = self.level,rotation = self.rotation,retention = self.retention,encoding = "utf-8",colorize=True)# 配置日志输出到缓冲区logger.add(sink=self.log_capture,format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {module}.{function}() at line {line}-{message}",level=self.level)# 获取捕获的日志内容def get_captured_logs(self):self.log_capture.seek(0)return self.log_capture.getvalue()# 获取logger实例def get_logger(self):return loggerif __name__ == '__main__':loggerconfig_info = Logconfig(log_file_dir=log_path, log_name='case_log_info.log', level='DEBUG')logger = loggerconfig_info.get_logger()logger.debug('调试日志')logger.info('普通日志')logger.warning('告警日志')logger.error('错误日志')# 将捕获的日志附加到 Allure 报告# captured_logs = loggerconfig_info.get_captured_logs()# allure.attach(captured_logs, name="Test Logs", attachment_type=allure.attachment_type.TEXT)
测试用例调用:
方法一:
用例中实例化logger
from common.log_info import Logconfig,log_path
logger = Logconfig(log_file_dir=log_path).get_logger()
@pytest.mark.parametrize('a,b,c', [(1, 2, 3), (4, 5, 6)])
def test_01(a, b,c):
with allure.step('test01'):
logger.info('测试case01')
print(f"传入的参数分别是:{a},{b},{c}")
方法二:
将封装好的Logconfig类在conftest中写成fixture自动执行
import allure
from common.log_info import log_path,Logconfig
@pytest.fixture(scope="function",autouse=True)
def log_test_infooo():
logger_config = Logconfig(log_file_dir=log_path, log_name='case_log_info.log', level='DEBUG')
logger = logger_config.get_logger()
yield logger
captured_logs = logger_config.get_captured_logs()
allure.attach(captured_logs, name="Test Logs", attachment_type=allure.attachment_type.TEXT)
scope="function" 作用域测试函数
autouse=True 自动执行不需要在用例中显式调用
from loguru import logger
@pytest.mark.parametrize('a,b,c', [(1, 2, 3), (4, 5, 6)])
def test_01(a, b,c):with allure.step('test01'):logger.info('测试case01')print(f"传入的参数分别是:{a},{b},{c}")
二、conftest中通过fixture输出日志
1 import os 2 from loguru import logger 3 @pytest.fixture(scope="function",autouse=True) 4 def configure_logger(): 5 # 配置 loguru 输出到文件 6 log_dir = "logs" 7 if not os.path.exists(log_dir): 8 os.makedirs(log_dir) 9 log_file = os.path.join(log_dir, "test.log") 10 logger.add(log_file, format="{time} {level} {module}.{function}() at line {line}-{message}", level="DEBUG",encoding="utf-8") 11 12 yield 13 # 测试结束后,将日志文件附加到 Allure 报告中 14 with open(log_file, "r", encoding="utf-8") as f: 15 allure.attach(f.read(), name="Test Logs", attachment_type=allure.attachment_type.TEXT)scope="function" 作用域测试函数
autouse=True 自动执行不需要在用例中显式调用
# 用例调用
from loguru import logger
@pytest.mark.parametrize('a,b,c', [(1, 2, 3), (4, 5, 6)])
def test_01(a, b,c):with allure.step('test01'):logger.info('测试case01')print(f"传入的参数分别是:{a},{b},{c}")执行后日志文件写入:
2025-03-28T10:36:32.414692+0800 INFO test_sz.test_01() at line 35-测试case01
2025-03-28T10:36:32.424637+0800 INFO test_sz.test_01() at line 35-测试case01
2025-03-28T10:36:32.424637+0800 INFO test_sz.test_01() at line 35-测试case01终端日志打印:
testcase/test_sz.py::test_01[1-2-3] 2025-03-28 10:38:09.512 | INFO | testcase.test_sz:test_01:35 - 测试case01
传入的参数分别是:1,2,3
PASSED
testcase/test_sz.py::test_01[4-5-6] 2025-03-28 10:38:09.519 | INFO | testcase.test_sz:test_01:35 - 测试case01
传入的参数分别是:4,5,6
PASSED
allure报告中附件日志信息:
如果想每个case日志在allure报告中单独展示,修改fixture方法:
@pytest.fixture(scope="function", autouse=True) def configure_logger(request):log_dir = "logs"if not os.path.exists(log_dir):os.makedirs(log_dir)log_file = os.path.join(log_dir, f"{request.node.name}.log") # 使用测试名称作为日志文件名 logger.remove()logger.add(log_file, format="{time} {level} {module}.{function}() at line {line}-{message}", level="DEBUG", encoding="utf-8")yieldwith open(log_file, "r", encoding="utf-8") as f:allure.attach(f.read(), name="Test Logs", attachment_type=allure.attachment_type.TEXT)