python自動(dòng)化測(cè)試之異常及日志操作實(shí)例分析
本文實(shí)例講述了python自動(dòng)化測(cè)試之異常及日志操作。分享給大家供大家參考,具體如下:
為了保持自動(dòng)化測(cè)試用例的健壯性,異常的捕獲及處理,日志的記錄對(duì)掌握自動(dòng)化測(cè)試執(zhí)行情況尤為重要,這里便詳細(xì)的介紹下在自動(dòng)化測(cè)試中使用到的異常及日志,并介紹其詳細(xì)的用法。
一、日志
打印日志是很多程序的重要需求,良好的日志輸出可以幫我們更方便的檢測(cè)程序運(yùn)行狀態(tài)。Python標(biāo)準(zhǔn)庫提供了logging模塊,切記Logger從來不直接實(shí)例化,其好處不言而喻,接下來慢慢講解Logging模塊提供了兩種記錄日志的方式。
- logging之模塊級(jí)別的函數(shù)方式記錄日志
import logging #設(shè)置日志,包括filename、level、format、filemode、stream,其中format屬性極其豐富,詳情可查看API文檔,這里只做簡(jiǎn)要介紹 logging.basicConfig(level = logging.INFO, format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt = "%Y/%m%d %H%M%S", filename = "log.txt") #消息級(jí)別,五級(jí) logging.debug("芹澤多摩雄") logging.info("真") logging.warning("男") logging.error("人") logging.critical("!")
- logging之日志系統(tǒng)的四大組件(日志器、處理器、過濾器、格式器)方式記錄日志
import logging # 生成日志實(shí)例,日志器 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”) #對(duì)接分支管道與源頭,處理器 logger.addHandler(handler_1) logger.addHandler(handler_2) #層級(jí)結(jié)構(gòu),logger的名稱是一個(gè)以'.'分割的層級(jí)結(jié)構(gòu),每個(gè)'.'后面的logger都是'.'前面的logger的children,通常配合過濾器一起使用 #過濾器 #。。。。保留 #開始記錄 logger.debug("芹澤多摩雄") logger.info("真") logger.warning("男") logger.error("人") logger.critical("!")
- 細(xì)心的盆友又可以發(fā)現(xiàn),可以發(fā)現(xiàn),logging有一個(gè)日志處理的主對(duì)象,其他處理方式都是通過addHandler添加進(jìn)去,這里采用logging.StreamHandler實(shí)現(xiàn)日志輸出到流(控制臺(tái)),也可以用FileHandler實(shí)現(xiàn)日志輸出到文件
- 日志回滾
import logging from logging.handlers import RotatingFileHandler logger = logging.getLogger(__name__) logger.setLevel(level = logging.INFO) #定義一個(gè)RotatingFileHandler,最多備份3個(gè)日志文件,每個(gè)日志文件最大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("!")
- 多模塊使用
#主模塊 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")
細(xì)心的盆友會(huì)再次發(fā)現(xiàn)其實(shí)對(duì)logger的命名很重要,首先在主模塊定義了logger'mainModule',并對(duì)它進(jìn)行了配置,子模塊可以共享父logger的定義和配置,所謂的父子logger是通過命名來識(shí)別,任意以'mainModule'開頭的logger都是它的子logger,例如'mainModule.sub'
- 事實(shí)上,縱使有繼承配置或者自定義的配置日志功能,但實(shí)際中的大項(xiàng)目中還是略麻煩的,這里主要用到JSON或者yaml進(jìn)行配置封裝,這樣加載該文件即可加載日志的配置,下回分解具體操作,最后來一發(fā)實(shí)例。
# -*- coding: utf-8 -*- __author__ = 'Secret608' import logging import time import os import re class Log(object): def __init__(self, loggerName): ''' 進(jìn)行日志初始化,包括存儲(chǔ)路徑、名稱、級(jí)別、調(diào)用文件等 ''' #基本屬性 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) #加到基本屬性中,得到一個(gè)完整的初始化對(duì)象 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")
二、異常
- 異常類型
- 內(nèi)置異常:Python的異常處理能力是很強(qiáng)大的,它有很多內(nèi)置異常,可向用戶準(zhǔn)確反饋出錯(cuò)信息。在Python中,異常也是對(duì)象,可對(duì)它進(jìn)行操作。BaseException是所有內(nèi)置異常的基類,但用戶定義的類并不直接繼承BaseException,所有的異常類都是從Exception繼承,且都在exceptions模塊中定義。
- 自定義異常:可以通過創(chuàng)建一個(gè)新的異常類擁有自己的異常,異常應(yīng)該是通過直接或間接的方式繼承自Exception類。比如創(chuàng)建了一個(gè)MyError類,基類為Exception,用于在異常觸發(fā)時(shí)輸出更多的信息。
- 異常捕獲
- 發(fā)生異常時(shí),我們就需要對(duì)異常進(jìn)行捕獲,然后進(jìn)行相應(yīng)的處理。python的異常捕獲常用try...except...結(jié)構(gòu),把可能發(fā)生錯(cuò)誤的語句放在try模塊里,用except來處理異常,每一個(gè)try,都必須至少對(duì)應(yīng)一個(gè)except。此外,與python異常相關(guān)的關(guān)鍵字主要有:try/except、pass、as(定義異常實(shí)例)、else、finally、raise。
- 捕獲所有異常:
# -*- coding: utf-8 -*- #異常處理的語法: try: #執(zhí)行可能出現(xiàn)異常的語句 except '異常名字': #出現(xiàn)異常執(zhí)行的語句 else: #執(zhí)行沒有出現(xiàn)異常的語句 finally: #異常與否都執(zhí)行的語句 #demo try: a = 0 b = 1 c = b/a print(c) except ZeroDivisionError: print("分母不能為0") except NameError: print("名稱錯(cuò)誤") except (ZeroDivisionError, NameError): print("你的分母等于0或者變量名不存在") except Exception as e: print("你的變量名或者分母值確實(shí)沒錯(cuò),但是出現(xiàn)了其他的錯(cuò)誤,詳見%s" %e) d = 1 finally: print("聽說沒有錯(cuò)誤?不能忍,反正我要讓你難受!") if d == 1: raise ValueError("你有其它錯(cuò)誤") else: raise FuckError("開不開心?") #咦? FuckError是啥?貌似沒有定義啊,這里定義一波,屆時(shí)位置移動(dòng)到前面去 class FuckError(Exception): def __int__(self,*args,**keargs): super(FuckError,self).__int__(*args,**keargs)#python2 self.args = args print(args)
更多的異??蓞⒖碅PI(https://docs.python.org/3/library/exceptions.html#base-classes)
更多關(guān)于Python相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Python日志操作技巧總結(jié)》、《Python函數(shù)使用技巧總結(jié)》、《Python字符串操作技巧匯總》、《Python入門與進(jìn)階經(jīng)典教程》及《Python文件與目錄操作技巧匯總》
希望本文所述對(duì)大家Python程序設(shè)計(jì)有所幫助。
相關(guān)文章
python中threading超線程用法實(shí)例分析
這篇文章主要介紹了python中threading超線程用法,實(shí)例分析了Python中threading模塊的相關(guān)使用技巧,需要的朋友可以參考下2015-05-05關(guān)于TensorFlow新舊版本函數(shù)接口變化詳解
今天小編就為大家分享一篇關(guān)于TensorFlow新舊版本函數(shù)接口變化詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-02-02Python中l(wèi)ogging日志記錄到文件及自動(dòng)分割的操作代碼
這篇文章主要介紹了Python中l(wèi)ogging日志記錄到文件及自動(dòng)分割,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08