python自动化测试之异常及日志操作实例分析


Posted in Python onNovember 09, 2019

本文实例讲述了python自动化测试之异常及日志操作。分享给大家供大家参考,具体如下:

为了保持自动化测试用例的健壮性,异常的捕获及处理,日志的记录对掌握自动化测试执行情况尤为重要,这里便详细的介绍下在自动化测试中使用到的异常及日志,并介绍其详细的用法。

一、日志

打印日志是很多程序的重要需求,良好的日志输出可以帮我们更方便的检测程序运行状态。Python标准库提供了logging模块,切记Logger从来不直接实例化,其好处不言而喻,接下来慢慢讲解Logging模块提供了两种记录日志的方式。

  1. logging之模块级别的函数方式记录日志
import logging
#设置日志,包括filename、level、format、filemode、stream,其中format属性极其丰富,详情可查看API文档,这里只做简要介绍
logging.basicConfig(level = logging.INFO,
format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s',

datefmt = "%Y/%m%d %H%M%S",

filename = "log.txt")
#消息级别,五级
logging.debug("芹泽多摩雄") 
logging.info("真")
logging.warning("男")
logging.error("人")
logging.critical("!")
  1.   logging之日志系统的四大组件(日志器、处理器、过滤器、格式器)方式记录日志
import logging
# 生成日志实例,日志器
logger = logging.getLogger(__name__)
#基本单元的配置(LEVER)
logger.setLevel(level = logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
#生成管道分支,处理器
handler_1 = logging.FileHandler("log.txt")
handler_2 = logging.StreamHandler()
#自定义格式,格式器
handler_1.setFormater(formatter, “%Y-%m-%d %H:%M:%S”)
handler_2.setFormater(formatter, “%Y-%m-%d %H:%M:%S”)
#对接分支管道与源头,处理器
logger.addHandler(handler_1)
logger.addHandler(handler_2)
#层级结构,logger的名称是一个以'.'分割的层级结构,每个'.'后面的logger都是'.'前面的logger的children,通常配合过滤器一起使用
#过滤器
#。。。。保留
#开始记录
logger.debug("芹泽多摩雄") 
logger.info("真")
logger.warning("男")
logger.error("人")
logger.critical("!")
  1. 细心的盆友又可以发现,可以发现,logging有一个日志处理的主对象,其他处理方式都是通过addHandler添加进去,这里采用logging.StreamHandler实现日志输出到流(控制台),也可以用FileHandler实现日志输出到文件
  2. 日志回滚
import logging
from logging.handlers import RotatingFileHandler
logger = logging.getLogger(__name__)
logger.setLevel(level = logging.INFO)
#定义一个RotatingFileHandler,最多备份3个日志文件,每个日志文件最大1K
rHandler = RotatingFileHandler("log.txt",maxBytes = 1*1024,backupCount = 3)
rHandler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
rHandler.setFormatter(formatter)
console = logging.StreamHandler()
console.setLevel(logging.INFO)
console.setFormatter(formatter)
logger.addHandler(rHandler)
logger.addHandler(console)
logger.debug("芹泽多摩雄") 
logger.info("真")
logger.warning("男")
logger.error("人")
logger.critical("!")
  1. 多模块使用
#主模块
import logging
import subModule
logger = logging.getLogger("mainModule")
logger.setLevel(level = logging.INFO)
handler = logging.FileHandler("log.txt")
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
console = logging.StreamHandler()
console.setLevel(logging.INFO)
console.setFormatter(formatter)
logger.addHandler(handler)
logger.addHandler(console)
#子模块
import logging
module_logger = logging.getLogger("mainModule.sub")
class SubModuleClass(object):
  def __init__(self):
    self.logger = logging.getLogger("mainModule.sub.module")

细心的盆友会再次发现其实对logger的命名很重要,首先在主模块定义了logger'mainModule',并对它进行了配置,子模块可以共享父logger的定义和配置,所谓的父子logger是通过命名来识别,任意以'mainModule'开头的logger都是它的子logger,例如'mainModule.sub'

  1. 事实上,纵使有继承配置或者自定义的配置日志功能,但实际中的大项目中还是略麻烦的,这里主要用到JSON或者yaml进行配置封装,这样加载该文件即可加载日志的配置,下回分解具体操作,最后来一发实例。
# -*- coding: utf-8 -*-
__author__ = 'Secret608'
import logging
import time
import os
import re
class Log(object):
  def __init__(self, loggerName):
      '''
      进行日志初始化,包括存储路径、名称、级别、调用文件等
      '''
      #基本属性
      self.logger = logging.getLogger(loggerName)
      self.logger.setLevel(logging.WARNING)
      #特有属性(文件地址+日志记录格式)
      rq = time.strftime('%Y%m%d_%H%M%S', time.localtime(time.time()))
      log_path = os.path.join(os.path.dirname(os.getcwd()), 'logs')
      log_title = os.path.join(log_path, loggerName + '_'+ rq) + ".log"
      formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
      log = logging.FileHandler(log_title)
      log.setFormatter(formatter)
      #加到基本属性中,得到一个完整的初始化对象
      self.logger.addHandler(log)
  def getLog(self):
    return self.logger
  def delLog(self, fileName):
    log_path = os.path.join(os.path.dirname(os.getcwd()), 'logs')
    regexp = re.compile('^'+fileName+'s.*')
    filelist = os.listdir(log_path)
    try:
      [os.remove(os.path.join(log_path, i)) for i in filelist if regexp.match(i) == None]
    except WindowsError:
      pass
    else:
      return "ok"
if __name__ == "__main__":
  a = Log("hah")
  a.delLog("hah")

二、异常

  • 异常类型
    • 内置异常:Python的异常处理能力是很强大的,它有很多内置异常,可向用户准确反馈出错信息。在Python中,异常也是对象,可对它进行操作。BaseException是所有内置异常的基类,但用户定义的类并不直接继承BaseException,所有的异常类都是从Exception继承,且都在exceptions模块中定义。
    • 自定义异常:可以通过创建一个新的异常类拥有自己的异常,异常应该是通过直接或间接的方式继承自Exception类。比如创建了一个MyError类,基类为Exception,用于在异常触发时输出更多的信息。
  • 异常捕获
    • 发生异常时,我们就需要对异常进行捕获,然后进行相应的处理。python的异常捕获常用try...except...结构,把可能发生错误的语句放在try模块里,用except来处理异常,每一个try,都必须至少对应一个except。此外,与python异常相关的关键字主要有:try/except、pass、as(定义异常实例)、else、finally、raise。
    • 捕获所有异常:
# -*- coding: utf-8 -*-
#异常处理的语法:
try:
  #执行可能出现异常的语句
except '异常名字':
  #出现异常执行的语句
else:
  #执行没有出现异常的语句
finally:
  #异常与否都执行的语句
#demo
try:
  a = 0
  b = 1
  c = b/a
  print(c)
except ZeroDivisionError:
  print("分母不能为0")
except NameError:
  print("名称错误")
except (ZeroDivisionError, NameError):
  print("你的分母等于0或者变量名不存在")
except Exception as e:
  print("你的变量名或者分母值确实没错,但是出现了其他的错误,详见%s" %e)
  d = 1  
finally:
  print("听说没有错误?不能忍,反正我要让你难受!")
  if d == 1:
    raise ValueError("你有其它错误")
  else:
    raise FuckError("开不开心?")
  #咦? FuckError是啥?貌似没有定义啊,这里定义一波,届时位置移动到前面去
  class FuckError(Exception):
    def __int__(self,*args,**keargs):
      super(FuckError,self).__int__(*args,**keargs)#python2
      self.args = args
      print(args)

更多的异常可参看API(https://docs.python.org/3/library/exceptions.html#base-classes)

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
sublime python3 输入换行不结束的方法
Apr 19 Python
Python单元测试实例详解
May 25 Python
Python使用logging模块实现打印log到指定文件的方法
Sep 05 Python
15行Python代码实现网易云热门歌单实例教程
Mar 10 Python
详解Python中is和==的区别
Mar 21 Python
Python微信操控itchat的方法
May 31 Python
Python中使用双下划线防止类属性被覆盖问题
Jun 27 Python
python图形绘制奥运五环实例讲解
Sep 14 Python
python中的RSA加密与解密实例解析
Nov 18 Python
tensorflow 分类损失函数使用小记
Feb 18 Python
Python基于yield遍历多个可迭代对象
Mar 12 Python
Python爬虫入门案例之爬取去哪儿旅游景点攻略以及可视化分析
Oct 16 Python
Python多线程模块Threading用法示例小结
Nov 09 #Python
Python for循环及基础用法详解
Nov 08 #Python
python常用排序算法的实现代码
Nov 08 #Python
python分布式编程实现过程解析
Nov 08 #Python
详解mac python+selenium+Chrome 简单案例
Nov 08 #Python
python manage.py runserver流程解析
Nov 08 #Python
详解python中docx库的安装过程
Nov 08 #Python
You might like
星际玩家的三大定律
2020/03/04 星际争霸
关于时间计算的结总
2006/12/06 PHP
php记录日志的实现代码
2011/08/08 PHP
destoon调用discuz论坛中带图片帖子的实现方法
2014/08/21 PHP
给WordPress中的留言加上楼层号的PHP代码实例
2015/12/14 PHP
PHP实现根据数组某个键值大小进行排序的方法
2018/03/13 PHP
PHP实现微信提现功能(微信商城)
2019/11/21 PHP
js动态给table添加/删除tr的方法
2013/08/02 Javascript
js闭包用法实例详解
2016/12/13 Javascript
vue组件父子间通信之综合练习(聊天室)
2017/11/07 Javascript
vue实现仿淘宝结账页面实例代码
2017/11/08 Javascript
JavaScript判断日期时间差的实例代码
2018/03/01 Javascript
react写一个select组件的实现代码
2019/04/03 Javascript
了解javascript中let和var及const关键字的区别
2019/05/24 Javascript
js设置鼠标悬停改变背景色实现详解
2019/06/26 Javascript
浅谈vuex中store的命名空间
2019/11/08 Javascript
vue路由缓存的几种实现方式小结
2020/02/02 Javascript
EXTJS7实现点击拖拉选择文本
2020/12/17 Javascript
JavaScript实现跟随鼠标移动的盒子
2021/01/28 Javascript
python原始套接字编程示例分享
2014/02/21 Python
python time模块用法实例详解
2014/09/11 Python
简单介绍Python中的decode()方法的使用
2015/05/18 Python
python代码实现ID3决策树算法
2017/12/20 Python
python实现数据预处理之填充缺失值的示例
2017/12/22 Python
Numpy中转置transpose、T和swapaxes的实例讲解
2018/04/17 Python
python启动应用程序和终止应用程序的方法
2019/06/28 Python
Python3如何判断三角形的类型
2020/04/12 Python
pyinstaller打包找不到文件的问题解决
2020/04/15 Python
Bandier官网:奢侈、时尚前卫的健身服装首选目的地
2020/07/05 全球购物
一些PHP的面试题
2015/05/06 面试题
员工晚婚的请假条
2014/02/08 职场文书
社区服务活动报告
2015/02/05 职场文书
七一活动主持词
2015/06/29 职场文书
穷人该怎么创业?谨记以下几点
2019/07/11 职场文书
Python实现提取PDF简历信息并存入Excel
2022/04/02 Python
JavaScript中的LHS和RHS分析详情
2022/04/06 Javascript