Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 865|回复: 0

python自动化测试之异常及日志

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-4-28 16:03:12 | 显示全部楼层 |阅读模式

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

      一、日志

        打印日志是很多程序的重要需求,良好的日志输出可以帮我们更方便的检测程序运行状态。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("")

       

    2.   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("")

       

       

       

       

    3. 细心的盆友又可以发现,可以发现,logging有一个日志处理的主对象,其他处理方式都是通过addHandler添加进去,这里采用logging.StreamHandler实现日志输出到流(控制台),也可以用FileHandler实现日志输出到文件

    4. 日志回滚
      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("")
    5. 多模块使用
      #主模块
      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'

    6. 事实上,纵使有继承配置或者自定义的配置日志功能,但实际中的大项目中还是略麻烦的,这里主要用到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("你有其它错误") elseraise 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

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-1-3 14:22 , Processed in 0.060473 second(s), 30 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表