3分钟通过日志定位bug,这个技能测试人必须会
♥ 前 言
软件开发中通过日志记录程序的运行情况是一个开发的好习惯,对于错误排查和系统运维都有很大帮助。
Python 标准库自带了强大的 logging 日志模块,在各种 python 模块中得到广泛应用。
一、简单使用
- 入门小案例
import logging
logging.basicConfig(level=logging.DEBUG, #设置级别,根据等级显示format='%(asctime)s-[%(filename)s-->line:%(lineno)d]-%(levelname)s:% (message)s') # 设置输出格式
logging.debug('This is a debug log')
logging.info('This is a info log')
logging.warning('This is a warning log')
logging.error('This is a error log')
logging.critical('This is a critical log')
- 日志级别
根据不同情况设置了五种日志等级,不同情况输出不同等级的日志。
日志器设置的级别会过滤掉低于这个级别的日志
import logging
logging.basicConfig(level=logging.WARNING, #设置级别,根据等级显示format='%(asctime)s-[%(filename)s-->line:%(lineno)d]-%(levelname)s:% (message)s') # 设置输出格式
logging.debug('This is a debug log')
logging.info('This is a info log')
logging.warning('This is a warning log')
logging.error('This is a error log')
logging.critical('This is a critical log')
2020-09-11 17:39:26,667-WARNING-This is a warning log
2020-09-11 17:39:26,669-ERROR-This is a error log
2020-09-11 17:39:26,669-CRITICAL-This is a critical log
- 配置
basicConfig 方法支持一下关键字参数进行配置。
- 格式化规则
日志的输出格式可以通过下面格式自由组合输出
常用格式:%(asctime)s-[%(filename)s–>line:%(lineno)d]-%(levelname)s:% (message)s
import logging
logging.basicConfig(level=logging.DEBUG, #设置级别,根据等级显示format='%(asctime)s-[%(filename)s-->line:%(lineno)d]-%(levelname)s:% (message)s') # 设置输出格式
logging.debug('This is a debug log')
[DEBUG]-2020-09-11 17:36:50,125–4:This is a debug log
- 日志写到文件
只需要配置 filename 参数即可
import logging
logging.basicConfig(level=logging.WARNING, #设置级别,根据等级显示filename='example.log'format='%(asctime)s-[%(filename)s-->line:%(lineno)d]-%(levelname)s:% (message)s') # 设置输出格式
logging.debug('This is a debug log')
logging.info('This is a info log')
logging.warning('This is a warning log')
logging.error('This is a error log')
logging.critical('This is a critical log')
注意,配置了 fielname 后,日志将不会输出在控制台。
二、高级用法
简单的代码通过 logging 直接使用即可,如果要深入使用需要按照面向对象的方式使用 logging。
- 日志组件
logging 模块包含一下几个组件。
2.步骤
2.1 创建日志记录器
import logging
# 第一步创建一个logger,用来产生日志
logger = logging.getLogger('%s_log' % __name__)
logger.setLevel(logging.DEBUG) # 设置日志等级
通过 getLogger 这个方法可以创建一个日志记录器,注意要给名字否则返回根日志记录器。
通过 setLevel 设置日志记录器的等级。
2.2 创建日志处理器
# 创建一个文本处理器用来将日志写入到文件
file_handler = logging.FileHandler(filename='py34.log',encoding='utf-8')
file_handler.setLevel('WARNING') # 设置处理器的日志等级
# 创建一个控制台处理器用来将日志输出到控制台
console_handler = logging.StreamHandler()
console_handler.setLevel('INFO') # 设置控制台处理器的日志等级
日志处理器就是将日志发送到指定的位置。
- FileHandler 将日志发送到文件
- StreaHandler 将它可将日志记录输出发送到数据流例如 sys.stdout, sys.stderr 或任何文件类对象默认sys.stdout 即控制台。
- RotatingFileHandler 支持根据日志文件大小进行轮转
- TimedRotatingFileHandler 支持根据时间进行轮转日志文件
更多详情见官方文档
(https://docs.python.org/zh-cn/3/library/logging.handlers.html?utm_source=testingpai.com#module-logging.handlers)
2.3 创建格式化器
formatter = logging.Formatter(fmt='%(levelname)s %(asctime)s [%(filename)s-->line:%(lineno)d]:%(message)s')
格式化器需要设置到处理器上
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)
2.4 创建过滤器
过滤器用来过滤指定日志。具体使用略,一般用不到。
详情见官方文档
(https://docs.python.org/zh-cn/3/howto/logging-cookbook.html?utm_source=testingpai.com#filters-contextual)
2.5 将处理器添加到记录器上
logger.addHandler(file_handler)
logger.addHandler(console_handler)
2.6 记录日志
logger.info('This is a info')
2020-09-11 22:22:44,095-[–>line:1]-INFO:This is a info
logger.warning('This is a warning')
2020-09-11 22:23:20,337-[–>line:1]-WARNING:This is a warning
三、日志模块封装
- 功能分析
能够自定义日志器名
能够自定义日志文件名和路径
能够自定义日志文件编码方式
能够自定义日志格式
使用时间轮转处理器,并能够配置
- 封装成函数
在 common 目录下创建模块 log_handler.py 在其中创建如下函数。
import logging
from logging.handlers import TimedRotatingFileHandlerdef get_logger(name, filename, encoding='utf-8', fmt=None, when='d', interval=1, backup_count=7, debug=False):""":param name: 日志器的名字:param filename: 日志文件名(包含路径):param encoding: 字符编码:param fmt: 日志格式:param when: 日志轮转时间单位:param interval: 间隔:param backup_count: 日志文件个数:param debug: 调试模式:return:"""logger = logging.getLogger(name)logger.setLevel(logging.DEBUG)# 文件处理器的等级一般情况一定比控制台要高if debug:file_level = logging.DEBUGconsole_level = logging.DEBUGelse:file_level = logging.WARNINGconsole_level = logging.INFOif fmt is None:fmt = '%(levelname)s %(asctime)s [%(filename)s-->line:%(lineno)d]:%(message)s'file_handler = TimedRotatingFileHandler(filename=filename, when=when, interval=interval, backupCount=backup_count, encoding=encoding)file_handler.setLevel(file_level)console_handler = logging.StreamHandler()console_handler.setLevel(console_level)formatter = logging.Formatter(fmt=fmt)file_handler.setFormatter(formatter)console_handler.setFormatter(formatter)logger.addHandler(file_handler)logger.addHandler(console_handler)return loggerif __name__ == '__main__':log = get_logger(name='py41', filename='py41.log', debug=True, when='s')log.info('我是普通信息')import timetime.sleep(3)log.warning('我是警告信息')
四、应用到项目中
- 导入
日志器生成函数的导入不能像 Excel 数据读取函数一样,每个用例模块里都导入一遍。因为它返回一个日志器对象,当多次调用日志器生成函数,且日志器名称相同时,会给同一个日志器添加多个日志处理器,从而出现重复记录日志器的问题。
为了解决上面的问题,在 common 文件夹下创建一个名为 init.py 的文件,在 common 模块被导入时会自动执行这个文件里的代码,且只会执行一次。
在 init.py 文件编写如下代码:
from .log_handler import get_logger
logger = get_logger('py41', 'py38.log')
那么在项目中的其他模块中就可以通过如下代码导入
from common import logger
从而可以保证在项目执行过程中,get_logger 方法只会执行一遍。
- 记录日志
日志的作用是记录程序的运行状态和当程序出现问题时能提供定位分析错误的依据。
什么时候需要记录日志,记录什么日志,根据每个人对程序的理解,以及经验。
我们的项目中,在用例执行的过程是核心,所以我们的日志也是围绕着用例的执行。
使用日志记录每个用例的测试数据,和测试结果,代码如下:
...
@list_data(*cases)def test_login(self, case):"""登陆测试"""logger.info('测试用例【{}】开始测试'.format(case['title']))# 1. 测试数据# 传入进来的case参数logger.info('测试用例【{}】的测试数据是:{}'.format(case['title'], case))# 2. 测试步骤res = login_check(case['username'], case['password'])logger.info('测试用例【{}】的测试结果是:{}'.format(case['title'], res))# 3. 断言try:self.assertEqual(res, case['expect'])except AssertionError as e:logger.error('测试用例【{}】断言失败'.format(case['title']))raise eelse:logger.info('测试用例【{}】断言成功'.format(case['title']))finally:logger.info('测试用例【{}】测试结束')
下面是配套资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!
最后: 可以在公众号:伤心的辣条 ! 免费领取一份216页软件测试工程师面试宝典文档资料。以及相对应的视频学习教程免费分享!,其中包括了有基础知识、Linux必备、Shell、互联网程序原理、Mysql数据库、抓包工具专题、接口测试工具、测试进阶-Python编程、Web自动化测试、APP自动化测试、接口自动化测试、测试高级持续集成、测试架构开发测试框架、性能测试、安全测试等。
学习不要孤军奋战,最好是能抱团取暖,相互成就一起成长,群众效应的效果是非常强大的,大家一起学习,一起打卡,会更有学习动力,也更能坚持下去。你可以加入我们的测试技术交流扣扣群:914172719(里面有各种软件测试资源和技术讨论)
喜欢软件测试的小伙伴们,如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏” 一键三连哦!
好文推荐
转行面试,跳槽面试,软件测试人员都必须知道的这几种面试技巧!
面试经:一线城市搬砖!又面软件测试岗,5000就知足了…
面试官:工作三年,还来面初级测试?恐怕你的软件测试工程师的头衔要加双引号…
什么样的人适合从事软件测试工作?
那个准点下班的人,比我先升职了…
测试岗反复跳槽,跳着跳着就跳没了…
3分钟通过日志定位bug,这个技能测试人必须会相关推荐
- 测试使用linux日志定位BUG,Web测试中定位bug方法
在web测试过程中,经常会遇到页面中内容或数据显示错误,甚至不显示,第一反应就是BUG,进一步了解这个BUG的问题出在那里,是测试人员需要掌握的,可以简单的使用浏览器自带开发者工具.数据库工具配合去排 ...
- 别乱用,这样打日志定位 Bug 又快又准!
点击关注公众号,实用技术文章及时了解 来源:blog.csdn.net/linsongbin1/article/ details/90349661 概述 日常工作中,程序员需要经常处理线上的各种大小故 ...
- 测试工程师用 Shell 定位 Bug 的正确姿势 | 福利
Shell 作为一门最常见的脚本语言,是测试工程师日常工作的重度依赖工具.相对 Python.Ruby 等其他脚本语言,Shell 就像一把趁手的军用匕首,轻量敏捷,是深入分析待测系统的利器,也是自动 ...
- 异步请求积压可视化|如何 1 分钟内快速定位函数计算积压问题
作者 | 千风 本文分为三个部分:概述中引入了积压问题,并介绍了函数计算异步调用基本链路:并在指标介绍部分详细介绍了指标查看方式,分类解读了不同的指标含义:最后以一个常见的异步请求积压场景为例,介绍如 ...
- tomcat 404错误 原因_软件测试人员定位bug原因的10大妙招分享
作为一名软件测试人员,日常工作与bug是息息相关的.在发现bug之后,首先要做的就是定位bug,确定bug的存在,然后才是分析bug产生的原因并解决bug. 无论是自己找到的bug,还是开发修复后告诉 ...
- Web测试中定位bug方法
原文:https://www.jianshu.com/p/696474d96bde 在web测试过程中,经常会遇到页面中内容或数据显示错误,甚至不显示,第一反应就是BUG,进一步了解这个BUG的问题出 ...
- 阿里软件测试工程师手把手教学—如何快速定位bug 编写测试用例?
作为一个测试人员,如果你连常见的系统问题都不懂得分析,频繁地把前端人员问题分配给后端人员,把后端人员问题分配给前端人员,那么你在团队发展中的地位是显而易见的,声誉.赏识.加薪应该是你遥不可及的梦想. ...
- 软件测试-工作流程(需求分析评审、测试计划、测试用例、用例评审、执行测试、跟踪定位bug、测试报告、缺陷报告)
一.需求分析.评审 (1)需求分析 对要解决的问题进行详细的分析,弄清楚问题的要求,包括需要输入什么数据,要得到什么结果,最后应输出什么. ①如何做需求分析? 通读需求,对需求有个大致的了解,比如: ...
- 缺陷定位 | 分析推理定位BUG案例(三)
往期关联文章: 缺陷定位 | 测试发现了Bug,还要分析定位Bug?(一) 缺陷定位 | 如何精准效率分析推测BUG定位(二) 运营反馈,生产环境,WEB端管理后台,岗位审核详情,视频无法正常播放 表 ...
最新文章
- 对称加密算法AES之GCM模式简介及在OpenSSL中使用举例
- 81. 搜索旋转排序数组 II
- MySQL模糊查询—in关键字
- [Flexbox] Using order to rearrange flexbox children
- java 读取ppt文件_java使用poi读取ppt文件和poi读取excel、word示例
- Newsmy纽曼星云1000G移动硬盘拆解教程
- 机友分享 | 基于Gokit+机智云的低成本MCU红外遥控器
- mysql分页查询参数的含义_mysql分页查询详解
- DWC的1000M的MAC自环和PHY自环测试寄存器修改方式
- 关于浏览器的几个高度和宽度
- 项目管理学习总结(15)——技术负责人所需的四个核心能力
- Android 控件开发之ToggleButton
- threejs学习网址记录
- 【VB6|第17期】16进制颜色值与RGB值互相转换(含源码)
- 看程序员奶爸是如何通过代码给宝宝起名的~
- 《Java核心技术(第八版)》笔记之第6章接口与内部类
- 怎么用计算机算虚数,小E教你们如何用计算机算虚数
- 20万粉丝的技术大V是怎样练成的--胡忠想访谈
- UPS、ATS、STS、EPS分别是什么
- 点击页面其它地方隐藏该div
热门文章
- php代码自定义字段,[原创]栏目自定义字段调用教程及代码
- 【论文写作】Springboot人才招聘网站如何画系统流程图
- ​php mysql 图书管理系统网页毕业设计成品
- python get sheet_Python模块学习 - openpyxl
- gittrack_Git 追踪分支
- win7计算机记忆窗口,Win7系统关闭和打开搜索记忆功能的方法(图文教程)
- java 银行管理系统怎么储存账户信息_银行管理系统 实现用户注册 登录 存、取款 交易记录查询和修改用户信息等功能...
- python对数组分类_有效地从字典Python中对数组进行分类
- MySql中,复制旧表结构到新表
- 线段树(Segment Tree)