在自动化测试项目中日志是排查问题的 “第一线索”。当你的用例在 CI/CD 环境中失败、GUI 自动化脚本突然崩溃、接口请求返回异常时没有日志就等于 “两眼一抹黑”。Python 标准库中的 logging 模块正是为解决这个问题而生的专业日志工具 —— 它支持多级别日志、多输出目标、自定义格式是自动化测试项目中必不可少的组件。一、为什么不用 print而要用 logging很多新手在调试时习惯用 print() 打印信息但在正式的自动化测试项目中print 存在致命缺陷如无法区分日志级别所有信息混在一起排查问题时难以筛选无法同时输出到控制台和文件CI/CD 环境中运行后无法回溯日志无法自定义日志格式缺少时间戳、模块名、行号等关键信息无法控制日志开关上线后注释 / 删除所有 print 非常麻烦。logging 完美解决了这些问题它支持✅ 5 种日志级别精准控制输出范围✅ 同时输出到控制台、文件、网络等多个目标✅ 自定义日志格式包含时间戳、模块名、行号等调试信息✅ 灵活的配置方式支持全局配置和模块化配置二、logging 基础用法从全局日志开始logging 提供了开箱即用的全局配置方式适合快速调试或小型项目。示例 1基础全局日志import logging # 基础配置设置日志级别为 INFOINFO 及以上级别才会输出 logging.basicConfig(levellogging.INFO) # 不同级别的日志 logging.debug(This is a debug message) # 调试信息默认级别下不会输出 logging.info(This is an info message) # 普通信息 logging.warning(This is a warning message) # 警告信息 logging.error(This is an error message) # 错误信息 logging.critical(This is a critical message) # 严重错误日志级别金字塔从低到高DEBUG INFO WARNING ERROR CRITICALDEBUG 调试信息用于开发阶段记录详细的运行细节INFO 常规运行信息记录关键流程节点WARNING 警告信息不影响程序运行但需要关注ERROR 错误信息程序部分功能失败CRITICAL 严重错误程序无法继续运行。basicConfig 中设置的 level 决定了只有该级别及以上的日志才会被输出。level设置为debug时DEBUG以上输出import logging logging.basicConfig(levellogging.DEBUG) # 获取 Logger 对象名称为当前模块名推荐便于区分模块日志 logger logging.getLogger(__name__) if __name__ __main__: logger.debug(This is a debug message) logger.info(This is an info message) logger.warning(This is a warning message) logger.error(This is an error message) logger.critical(This is a critical message) # DEBUG以上输出 # DEBUG :__main__:This is a debug message # INFO:__main__:This is an info message # WARNING:__main__:This is a warning message # ERROR:__main__:This is an error message # CRITICAL:__main__:This is a critical messagelevel设置为WARNING时输出WARNING以上全部内容import logging logging.basicConfig(levellogging.WARNING) # 获取 Logger 对象名称为当前模块名推荐便于区分模块日志 logger logging.getLogger(__name__) if __name__ __main__: logger.debug(This is a debug message) logger.info(This is an info message) logger.warning(This is a warning message) logger.error(This is an error message) logger.critical(This is a critical message) # 输出WARNING以上全部内容 # WARNING:__main__:This is a warning message # ERROR:__main__:This is an error message # CRITICAL:__main__:This is a critical message日志配置 与 日志通用配置 区别优先取日志配置import logging #通用配置修改全局日志级别配置为WARNING logging.basicConfig(levellogging.WARNING) #日志配置对logger对象设置改日志对象的日志级别为DEBUG logger logging.getLogger(__name__) logger.setLevel(logging.DEBUG) if __name__ __main__: logger.debug(This is a debug message) logger.info(This is an info message) logger.warning(This is a warning message) logger.error(This is an error message) logger.critical(This is a critical message) # 输出DEBUG以上全部内容 # DEBUG:__main__:This is a debug message # INFO:__main__:This is an info message # WARNING:__main__:This is a warning message # ERROR:__main__:This is an error message # CRITICAL:__main__:This is a critical message三、进阶用法自定义 Logger 对象在大型项目中推荐使用自定义 Logger 对象而不是全局日志。它的优势是支持模块化日志不同模块的日志可以区分支持多个处理器Handler同时输出到控制台和文件支持独立配置日志级别和格式灵活性更高。示例 2自定义 Logger 并输出到控制台import logging # 获取 Logger 对象名称为当前模块名推荐便于区分模块日志 logger logging.getLogger(__name__) # 设置日志级别为 DEBUGDEBUG 及以上都会输出 logger.setLevel(logging.DEBUG) if __name__ __main__: logger.debug(This is a debug message) logger.info(This is an info message) logger.warning(This is a warning message) logger.error(This is an error message) logger.critical(This is a critical message)示例 3输出日志到文件通过创建文件处理器 FileHandler可以将日志同时写入文件便于后续排查问题import logging logger logging.getLogger(__name__) logger.setLevel(logging.DEBUG) # 创建文件处理器指定日志文件路径 file_handler logging.FileHandler(filenamelog_test.log, encodingutf-8) # 将处理器添加到 Logger 对象 logger.addHandler(file_handler) if __name__ __main__: logger.debug(This is a debug message) logger.info(This is an info message) logger.warning(This is a warning message) logger.error(This is an error message) logger.critical(This is a critical message)运行后日志会同时输出到目标文件log_test.log中。四、高级配置自定义日志格式默认的日志输出格式只有信息内容缺少关键的调试信息如时间、模块名、行号。通过 Formatter 可以自定义日志格式让每一条日志都包含完整的上下文信息。示例 4自定义日志格式import logging logger logging.getLogger(__name__) logger.setLevel(logging.DEBUG) # 1. 创建文件处理器 file_handler logging.FileHandler(test.log, encodingutf-8) # 2. 创建日志格式器 formatter logging.Formatter( fmt%(asctime)s | %(levelname)-8s | %(name)s:%(filename)s:%(lineno)d | %(message)s, datefmt%Y-%m-%d %H:%M:%S ) # 3. 将格式器设置到处理器 file_handler.setFormatter(formatter) # 4. 添加处理器到 Logger logger.addHandler(file_handler) if __name__ __main__: logger.debug(This is a debug message) logger.info(This is an info message) logger.warning(This is a warning message) logger.error(This is an error message) logger.critical(This is a critical message)对应文件test.log中每一条日志都包含完整的上下文信息2026-05-25 21:23:30 | DEBUG | __main__:my_logging.py:22 | This is a debug message 2026-05-25 21:23:30 | INFO | __main__:my_logging.py:23 | This is an info message 2026-05-25 21:23:30 | WARNING | __main__:my_logging.py:24 | This is a warning message 2026-05-25 21:23:30 | ERROR | __main__:my_logging.py:25 | This is an error message 2026-05-25 21:23:30 | CRITICAL | __main__:my_logging.py:26 | This is a critical message常用格式占位符说明占位符说明%(asctime)s日志记录的时间戳格式可自定义%(levelname)s日志级别DEBUG/INFO/WARNING/ERROR/CRITICAL%(name)sLogger 对象的名称通常为模块名%(filename)s日志记录发生的文件名%(lineno)d日志记录发生的行号%(funcName)s日志记录发生的函数名%(message)s日志消息本身五、自动化测试实战日志最佳实践在 GUI / 接口自动化测试项目中logging 有几个固定的使用场景和最佳实践1. 项目级日志配置推荐在项目根目录创建 logger_config.py统一配置日志所有模块直接导入使用# logger_config.py import logging import os from logging.handlers import RotatingFileHandler def setup_logger(name__name__, log_filelogs/test.log, max_size10*1024*1024, backup_count5): 项目级日志配置 :param name: Logger 名称建议用模块名 :param log_file: 日志文件路径 :param max_size: 单个日志文件最大大小默认10MB :param backup_count: 日志文件备份数量 # 创建日志目录 os.makedirs(os.path.dirname(log_file), exist_okTrue) logger logging.getLogger(name) logger.setLevel(logging.DEBUG) # 避免重复添加处理器 if logger.handlers: return logger # 1. 控制台处理器 console_handler logging.StreamHandler() console_handler.setLevel(logging.INFO) # 2. 文件处理器按大小切割日志避免单个文件过大 file_handler RotatingFileHandler( log_file, maxBytesmax_size, backupCountbackup_count, encodingutf-8 ) file_handler.setLevel(logging.DEBUG) # 3. 日志格式 formatter logging.Formatter( %(asctime)s | %(levelname)-8s | %(name)s:%(filename)s:%(lineno)d | %(message)s, datefmt%Y-%m-%d %H:%M:%S ) console_handler.setFormatter(formatter) file_handler.setFormatter(formatter) # 添加处理器 logger.addHandler(console_handler) logger.addHandler(file_handler) return logger在测试用例中直接使用# test_login.py from logger_config import setup_logger logger setup_logger(__name__) def test_login(): logger.info(开始执行登录用例) username admin password 123456 logger.debug(f使用账号{username}密码{password}) # 模拟登录操作 try: # 这里写实际的登录逻辑 logger.info(登录操作执行完成) except Exception as e: logger.error(f登录失败{str(e)}, exc_infoTrue) raise2. 关键场景日志记录用例执行前后记录用例名称、开始 / 结束时间关键操作节点如打开浏览器、输入账号、点击按钮、接口请求 / 响应异常信息 使用 logger.error(消息, exc_infoTrue) 记录完整的异常栈信息环境信息 记录测试环境URL、版本号、测试数据避免硬编码。3. 日志切割避免单个日志文件过大使用 RotatingFileHandler按大小切割或 TimedRotatingFileHandler按时间切割自动分割日志文件避免单个日志文件过大便于后续归档和排查。六、常见问题与避坑指南日志不输出检查日志级别设置确保设置的级别不高于日志调用级别日志重复输出是否多次添加 Handler在 setup_logger 中添加 if logger.handlers: 判断中文乱码FileHandler 初始化时指定 encodingutf-8日志文件路径不存在提前创建日志目录使用 os.makedirs(os.path.dirname(log_file), exist_okTrue)日志级别不生效basicConfig 只能配置一次后续修改无效推荐使用自定义 Logger 对象。七、总结logging 模块是 Python 自动化测试项目中不可或缺的组件它不仅能帮你记录关键信息更能在问题发生时提供完整的上下文大幅提升调试效率。核心知识点回顾日志级别DEBUG INFO WARNING ERROR CRITICAL通过setLevel控制输出范围三大核心组件Logger日志记录器、Handler输出处理器、Formatter日志格式器最佳实践项目级统一配置、模块化 Logger、日志切割、关键场景记录。掌握 logging 的使用你的自动化测试项目将从 “能跑” 升级为 “可维护、可追溯、易排查” 的专业级项目。后续我们可以结合 Allure 报告将日志嵌入测试报告中让失败用例的排查更直观。
16:logging 日志模块
在自动化测试项目中日志是排查问题的 “第一线索”。当你的用例在 CI/CD 环境中失败、GUI 自动化脚本突然崩溃、接口请求返回异常时没有日志就等于 “两眼一抹黑”。Python 标准库中的 logging 模块正是为解决这个问题而生的专业日志工具 —— 它支持多级别日志、多输出目标、自定义格式是自动化测试项目中必不可少的组件。一、为什么不用 print而要用 logging很多新手在调试时习惯用 print() 打印信息但在正式的自动化测试项目中print 存在致命缺陷如无法区分日志级别所有信息混在一起排查问题时难以筛选无法同时输出到控制台和文件CI/CD 环境中运行后无法回溯日志无法自定义日志格式缺少时间戳、模块名、行号等关键信息无法控制日志开关上线后注释 / 删除所有 print 非常麻烦。logging 完美解决了这些问题它支持✅ 5 种日志级别精准控制输出范围✅ 同时输出到控制台、文件、网络等多个目标✅ 自定义日志格式包含时间戳、模块名、行号等调试信息✅ 灵活的配置方式支持全局配置和模块化配置二、logging 基础用法从全局日志开始logging 提供了开箱即用的全局配置方式适合快速调试或小型项目。示例 1基础全局日志import logging # 基础配置设置日志级别为 INFOINFO 及以上级别才会输出 logging.basicConfig(levellogging.INFO) # 不同级别的日志 logging.debug(This is a debug message) # 调试信息默认级别下不会输出 logging.info(This is an info message) # 普通信息 logging.warning(This is a warning message) # 警告信息 logging.error(This is an error message) # 错误信息 logging.critical(This is a critical message) # 严重错误日志级别金字塔从低到高DEBUG INFO WARNING ERROR CRITICALDEBUG 调试信息用于开发阶段记录详细的运行细节INFO 常规运行信息记录关键流程节点WARNING 警告信息不影响程序运行但需要关注ERROR 错误信息程序部分功能失败CRITICAL 严重错误程序无法继续运行。basicConfig 中设置的 level 决定了只有该级别及以上的日志才会被输出。level设置为debug时DEBUG以上输出import logging logging.basicConfig(levellogging.DEBUG) # 获取 Logger 对象名称为当前模块名推荐便于区分模块日志 logger logging.getLogger(__name__) if __name__ __main__: logger.debug(This is a debug message) logger.info(This is an info message) logger.warning(This is a warning message) logger.error(This is an error message) logger.critical(This is a critical message) # DEBUG以上输出 # DEBUG :__main__:This is a debug message # INFO:__main__:This is an info message # WARNING:__main__:This is a warning message # ERROR:__main__:This is an error message # CRITICAL:__main__:This is a critical messagelevel设置为WARNING时输出WARNING以上全部内容import logging logging.basicConfig(levellogging.WARNING) # 获取 Logger 对象名称为当前模块名推荐便于区分模块日志 logger logging.getLogger(__name__) if __name__ __main__: logger.debug(This is a debug message) logger.info(This is an info message) logger.warning(This is a warning message) logger.error(This is an error message) logger.critical(This is a critical message) # 输出WARNING以上全部内容 # WARNING:__main__:This is a warning message # ERROR:__main__:This is an error message # CRITICAL:__main__:This is a critical message日志配置 与 日志通用配置 区别优先取日志配置import logging #通用配置修改全局日志级别配置为WARNING logging.basicConfig(levellogging.WARNING) #日志配置对logger对象设置改日志对象的日志级别为DEBUG logger logging.getLogger(__name__) logger.setLevel(logging.DEBUG) if __name__ __main__: logger.debug(This is a debug message) logger.info(This is an info message) logger.warning(This is a warning message) logger.error(This is an error message) logger.critical(This is a critical message) # 输出DEBUG以上全部内容 # DEBUG:__main__:This is a debug message # INFO:__main__:This is an info message # WARNING:__main__:This is a warning message # ERROR:__main__:This is an error message # CRITICAL:__main__:This is a critical message三、进阶用法自定义 Logger 对象在大型项目中推荐使用自定义 Logger 对象而不是全局日志。它的优势是支持模块化日志不同模块的日志可以区分支持多个处理器Handler同时输出到控制台和文件支持独立配置日志级别和格式灵活性更高。示例 2自定义 Logger 并输出到控制台import logging # 获取 Logger 对象名称为当前模块名推荐便于区分模块日志 logger logging.getLogger(__name__) # 设置日志级别为 DEBUGDEBUG 及以上都会输出 logger.setLevel(logging.DEBUG) if __name__ __main__: logger.debug(This is a debug message) logger.info(This is an info message) logger.warning(This is a warning message) logger.error(This is an error message) logger.critical(This is a critical message)示例 3输出日志到文件通过创建文件处理器 FileHandler可以将日志同时写入文件便于后续排查问题import logging logger logging.getLogger(__name__) logger.setLevel(logging.DEBUG) # 创建文件处理器指定日志文件路径 file_handler logging.FileHandler(filenamelog_test.log, encodingutf-8) # 将处理器添加到 Logger 对象 logger.addHandler(file_handler) if __name__ __main__: logger.debug(This is a debug message) logger.info(This is an info message) logger.warning(This is a warning message) logger.error(This is an error message) logger.critical(This is a critical message)运行后日志会同时输出到目标文件log_test.log中。四、高级配置自定义日志格式默认的日志输出格式只有信息内容缺少关键的调试信息如时间、模块名、行号。通过 Formatter 可以自定义日志格式让每一条日志都包含完整的上下文信息。示例 4自定义日志格式import logging logger logging.getLogger(__name__) logger.setLevel(logging.DEBUG) # 1. 创建文件处理器 file_handler logging.FileHandler(test.log, encodingutf-8) # 2. 创建日志格式器 formatter logging.Formatter( fmt%(asctime)s | %(levelname)-8s | %(name)s:%(filename)s:%(lineno)d | %(message)s, datefmt%Y-%m-%d %H:%M:%S ) # 3. 将格式器设置到处理器 file_handler.setFormatter(formatter) # 4. 添加处理器到 Logger logger.addHandler(file_handler) if __name__ __main__: logger.debug(This is a debug message) logger.info(This is an info message) logger.warning(This is a warning message) logger.error(This is an error message) logger.critical(This is a critical message)对应文件test.log中每一条日志都包含完整的上下文信息2026-05-25 21:23:30 | DEBUG | __main__:my_logging.py:22 | This is a debug message 2026-05-25 21:23:30 | INFO | __main__:my_logging.py:23 | This is an info message 2026-05-25 21:23:30 | WARNING | __main__:my_logging.py:24 | This is a warning message 2026-05-25 21:23:30 | ERROR | __main__:my_logging.py:25 | This is an error message 2026-05-25 21:23:30 | CRITICAL | __main__:my_logging.py:26 | This is a critical message常用格式占位符说明占位符说明%(asctime)s日志记录的时间戳格式可自定义%(levelname)s日志级别DEBUG/INFO/WARNING/ERROR/CRITICAL%(name)sLogger 对象的名称通常为模块名%(filename)s日志记录发生的文件名%(lineno)d日志记录发生的行号%(funcName)s日志记录发生的函数名%(message)s日志消息本身五、自动化测试实战日志最佳实践在 GUI / 接口自动化测试项目中logging 有几个固定的使用场景和最佳实践1. 项目级日志配置推荐在项目根目录创建 logger_config.py统一配置日志所有模块直接导入使用# logger_config.py import logging import os from logging.handlers import RotatingFileHandler def setup_logger(name__name__, log_filelogs/test.log, max_size10*1024*1024, backup_count5): 项目级日志配置 :param name: Logger 名称建议用模块名 :param log_file: 日志文件路径 :param max_size: 单个日志文件最大大小默认10MB :param backup_count: 日志文件备份数量 # 创建日志目录 os.makedirs(os.path.dirname(log_file), exist_okTrue) logger logging.getLogger(name) logger.setLevel(logging.DEBUG) # 避免重复添加处理器 if logger.handlers: return logger # 1. 控制台处理器 console_handler logging.StreamHandler() console_handler.setLevel(logging.INFO) # 2. 文件处理器按大小切割日志避免单个文件过大 file_handler RotatingFileHandler( log_file, maxBytesmax_size, backupCountbackup_count, encodingutf-8 ) file_handler.setLevel(logging.DEBUG) # 3. 日志格式 formatter logging.Formatter( %(asctime)s | %(levelname)-8s | %(name)s:%(filename)s:%(lineno)d | %(message)s, datefmt%Y-%m-%d %H:%M:%S ) console_handler.setFormatter(formatter) file_handler.setFormatter(formatter) # 添加处理器 logger.addHandler(console_handler) logger.addHandler(file_handler) return logger在测试用例中直接使用# test_login.py from logger_config import setup_logger logger setup_logger(__name__) def test_login(): logger.info(开始执行登录用例) username admin password 123456 logger.debug(f使用账号{username}密码{password}) # 模拟登录操作 try: # 这里写实际的登录逻辑 logger.info(登录操作执行完成) except Exception as e: logger.error(f登录失败{str(e)}, exc_infoTrue) raise2. 关键场景日志记录用例执行前后记录用例名称、开始 / 结束时间关键操作节点如打开浏览器、输入账号、点击按钮、接口请求 / 响应异常信息 使用 logger.error(消息, exc_infoTrue) 记录完整的异常栈信息环境信息 记录测试环境URL、版本号、测试数据避免硬编码。3. 日志切割避免单个日志文件过大使用 RotatingFileHandler按大小切割或 TimedRotatingFileHandler按时间切割自动分割日志文件避免单个日志文件过大便于后续归档和排查。六、常见问题与避坑指南日志不输出检查日志级别设置确保设置的级别不高于日志调用级别日志重复输出是否多次添加 Handler在 setup_logger 中添加 if logger.handlers: 判断中文乱码FileHandler 初始化时指定 encodingutf-8日志文件路径不存在提前创建日志目录使用 os.makedirs(os.path.dirname(log_file), exist_okTrue)日志级别不生效basicConfig 只能配置一次后续修改无效推荐使用自定义 Logger 对象。七、总结logging 模块是 Python 自动化测试项目中不可或缺的组件它不仅能帮你记录关键信息更能在问题发生时提供完整的上下文大幅提升调试效率。核心知识点回顾日志级别DEBUG INFO WARNING ERROR CRITICAL通过setLevel控制输出范围三大核心组件Logger日志记录器、Handler输出处理器、Formatter日志格式器最佳实践项目级统一配置、模块化 Logger、日志切割、关键场景记录。掌握 logging 的使用你的自动化测试项目将从 “能跑” 升级为 “可维护、可追溯、易排查” 的专业级项目。后续我们可以结合 Allure 报告将日志嵌入测试报告中让失败用例的排查更直观。