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

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

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

一、日志

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

  1. logging之模块级别的函数方式记录日志

1

2

3

4

5

6

7

8

9

10

11

12

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之日志系统的四大组件(日志器、处理器、过滤器、格式器)方式记录日志

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

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. 日志回滚

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

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. 多模块使用

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

#主模块

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进行配置封装,这样加载该文件即可加载日志的配置,下回分解具体操作,最后来一发实例。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

# -*- 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。
    • 捕获所有异常:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

# -*- 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) 

​现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
qq群号:485187702【暗号:csdn11】
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
视频+文档+PDF+面试题可以关注公众号:【软件测试小dao】

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走! 希望能帮助到你!【100%无套路免费领取】

  • 29
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值