一、python logging模块
python logging模块提供了logger、handler、filter、formatter等基础类。
其中:
1、logger: 提供日志接口,供应用程序调用。logger最常用的操作有两大类:配置和发送日志消息。
2、handler:将日志记录发送到合适的目的,比如文件、socket等等。一个logger对象可以通过addhandler方法添加0到N个handler,每个hangdler又可以定义不同的日志级别,以实现日志分级过滤。
3、filter:提供了一种优雅的方式决定一个日志记录是否发送到handler。
4、formatter:指定日志记录的输出格式。formatter的构造方法需要两个参数:消息的格式字符串和日期字符串,这两个参数是可选的。
二、日志的封装
log.py
# Author:Xueyun
# -*- coding:utf-8 -*-
import logging
'''配置日志文件,输出信息级别以上的日志'''
class Log:
def __init__(self):
#日志名称
self.logname = "mylog"
def setMsg(self, level, msg):
logger = logging.getLogger()
#创建一个handler写入所有日志
fh = logging.FileHandler("E:\\Pycharm_projects\\1\\logger"+ "mylog.log")
#创建一个handler输出到控制台
ch = logging.StreamHandler()
#定义日志输出格式,%(asctime)s: 打印日志的时间;%(levelname)s: 打印日志级别名称,%(message)s: 打印日志信息
formater = logging.Formatter("%(asctime)s %(levelname)s %(message)s")
#将定义好的输出形式添加到handler
fh.setFormatter(formater)
ch.setFormatter(formater)
#添加handle,一个logger对象可以通过addhandler方法添加0到N个handler,每个hangdler又可以定义不同的日志级别,以实现日志分级过滤
logger.addHandler(fh)
logger.addHandler(ch)
#添加日志信息,输出信息级别以上的日志
logger.setLevel(logging.INFO)
if level == 'debug':
logger.debug(msg)
elif level == 'info':
logger.info(msg)
elif level == 'warning':
logger.warning(msg)
elif level == 'error':
logger.error(msg)
#移除handler,否则日志会重复输出
logger.removeHandler(fh)
logger.removeHandler(ch)
fh.close()
def debug(self, msg):
self.setMsg('debug', msg)
def info(self, msg):
self.setMsg('info', msg)
def warning(self, msg):
self.setMsg('warning', msg)
def error(self, msg):
self.setMsg('error', msg)
三、日志在自动化测试中的应用
base_page.py,接https://blog.csdn.net/weixin_42228683/article/details/102248514
# Author:Xueyun
# -*- coding:utf-8 -*-
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from logger.log import Log
'''定义页面基础类,封装所有页面公用的方法'''
class BasePage(object):
# 初始化driver,url,pagetitle
def __init__(self, selenium_driver, base_url, pagetitle):
self.driver = selenium_driver
self.base_url = base_url
self.pagetitle = pagetitle
self.mylog = Log()
# 使用title获取当前窗口title,以此来检查输入的title是否在当前title中
def on_page(self, pagetitle):
return pagetitle in self.driver.title
# 打开页面,并检验页面链接是否正确
'''以单下划线开头的方法,在使用import *时,该方法不会被导入,保证该方法为类私有'''
def _open(self, url, pagetitle):
# 校验打开的title是否与配置title一致
try:
# 打开链接
self.driver.get(url)
# 窗口最大化
self.driver.maximize_window()
assert self.on_page(pagetitle), u"打开页面失败 %s" % url
except:
self.mylog.error(u"未能正确打开页面:"+ url)
#调用_open方法打开链接
def open(self):
self._open(self.base_url, self.pagetitle)
#元素定位方法
def find_element(self, *loc):
try:
WebDriverWait(self.driver,10).until(EC.visibility_of_element_located(loc))
return self.driver.find_element(*loc)
except:
self.mylog.error(u"%s 页面中未能找到%s元素"%(self, loc))
#send_keys方法
def send_keys(self,loc,value,clear_first=True,click_first=True):
try:
loc = getattr(self,'_%s'%loc)
if click_first:
self.find_element(*loc).click()
if clear_first:
self.find_element(*loc).clear()
self.find_element(*loc).send_keys(value)
except AttributeError:
self.mylog.error(u"%s 页面中未能找到%s元素" % (self, loc))
filename: 指定日志输出文件名
filemode:和file函数的意义相同,指定日志文件的打开模式,‘w或a’
format:指定日志输出格式和内容,format可以输出很多有用的信息,如上例所示:
%(levelno)s: 打印日志级别的数值
%(levelname)s: 打印日志级别名称
%(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0]
%(filename)s: 打印当前执行程序名
%(funcName)s: 打印日志的当前函数
%(lineno)d: 打印日志的当前行号
%(asctime)s: 打印日志的时间
%(thread)d: 打印线程ID
%(threadName)s: 打印线程名称
%(process)d: 打印进程ID
%(message)s: 打印日志信息
datefmt:指定时间格式,同time.strtime()
level:指定日志级别,默认为logging.WARNING
stream:指定日志的输出流,可以指定输出到sys.stderr, sys.stdout或文件,默认输出到sys.stderr,当stream和filename同时指定时,stream被忽略。