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 相关文章推荐
python生成指定尺寸缩略图的示例
May 07 Python
python将MongoDB里的ObjectId转换为时间戳的方法
Mar 13 Python
Python中的localtime()方法使用详解
May 22 Python
详解Python中heapq模块的用法
Jun 28 Python
Python中模块与包有相同名字的处理方法
May 05 Python
Python实现的快速排序算法详解
Aug 01 Python
TensorFlow搭建神经网络最佳实践
Mar 09 Python
python调用xlsxwriter创建xlsx的方法
May 03 Python
浅谈Pandas Series 和 Numpy array中的相同点
Jun 28 Python
在django admin中添加自定义视图的例子
Jul 26 Python
django 自定义filter 判断if var in list的例子
Aug 20 Python
Python 2.6.6升级到Python2.7.15的详细步骤
Dec 14 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
PHP数据库操作面向对象的优点
2006/10/09 PHP
php设计模式之单例模式使用示例
2014/01/20 PHP
分享一个php 的异常处理程序
2014/06/22 PHP
javascript document.images实例
2008/05/27 Javascript
JavaScript函数、方法、对象代码
2008/10/29 Javascript
有关DOM元素与事件的3个谜题
2010/11/11 Javascript
jquery利用event.which方法获取键盘输入值的代码
2011/10/09 Javascript
jQuery EasyUI API 中文文档 - NumberSpinner数值微调器使用介绍
2011/10/21 Javascript
javascript中创建对象的几种方法总结
2013/11/01 Javascript
juery框架写的弹窗效果适合新手
2013/11/27 Javascript
div浮层,滚动条移动,位置保持不变的4种方法汇总
2013/12/11 Javascript
图片翻转效果具体实现代码
2014/01/09 Javascript
Vue表单验证插件Vue Validator使用方法详解
2017/04/07 Javascript
详解如何在Vue里建立长按指令
2018/08/20 Javascript
微信小程序自定义select下拉选项框组件的实现代码
2018/08/28 Javascript
Python画图学习入门教程
2016/07/01 Python
python中装饰器级连的使用方法示例
2017/09/29 Python
python对象与json相互转换的方法
2019/05/07 Python
Django框架使用mysql视图操作示例
2019/05/15 Python
python如何统计代码运行的时长
2019/07/24 Python
python实现桌面气泡提示功能
2019/07/29 Python
python代码 FTP备份交换机配置脚本实例解析
2019/08/01 Python
pytorch中的自定义反向传播,求导实例
2020/01/06 Python
利用css3画个同心圆示例代码
2017/07/03 HTML / CSS
基于Html5实现的语音搜索功能
2019/05/13 HTML / CSS
估算杭州有多少软件工程师
2015/08/11 面试题
历史专业大学生职业生涯规划书
2014/03/13 职场文书
2014物价局民主生活会对照检查材料思想汇报
2014/09/24 职场文书
房产协议书范本2014
2014/09/30 职场文书
离婚协议书范文
2015/01/26 职场文书
2015年科室工作总结
2015/04/10 职场文书
三国演义读书笔记
2015/06/25 职场文书
高中生综合素质评价范文
2015/08/18 职场文书
基于JavaScript实现省市联动效果
2021/06/22 Javascript
netty 实现tomcat的示例代码
2022/06/05 Servers
Python+SeaTable实现计算两个日期间的工作日天数
2022/07/07 Python