1、logging模块
DEBUG
、
INFO
、
WARNING
、
ERROR
、
CRITICAL
2、日志用法
2.1 基本用法
(1)设置日志级别
-
默认:logging中默认的日志级别为WARNING,程序中大于等于该级别的日志才能输出,小于该级别的日志不会被打印出来。
-
格式:
logging.basicConfig(level=logging.DEBUG)
(2)设置日志格式
-
默认的日志的格式为:
format=日志级别:Logger名称:日志内容
-
自定义日志格式:
logging.basicConfig(format="%(levelname)s:%(name)s:%(message)s")
(3)日志信息输出到文件
-
默认情况下Python的logging模块将日志打印到了控制台
-
格式:
logging.basicConfig(filename="a.log")
-
代码示例:
import logging
fmt = '%(asctime)s %(levelname)s [%(name)s] [%(filename)s(%(funcName)s:%(lineno)d)] - %(message)s'
logging.basicConfig(filename="a.log", level=logging.INFO, format=fmt)
logging.debug("调试")
logging.info("信息")
logging.warning("警告")
logging.error("错误")
2.2 高级用法
(1)logging日志模块四大组件
-
Logger: 日志器,提供了程序使用日志的入口
-
Handler: 处理器,将logger创建的日志记录发送到合适的目的输出
-
Formatter: 格式器,决定日志记录的最终输出格式
-
Filter: 过滤器,提供了更细粒度的控制工具来决定输出哪条日志记录,丢弃哪条日志记录
(2)Logger类
-
创建Logger对象:logger = logging.getLogger() 或者 logger = logging.getLogger("myLogger")
-
打印日志信息:
logger.info()
logger.warning()
-
设置日志级别:logger.setLevel()
-
添加handler对象:logger.addHandler()
-
添加filter对象:logger.addFilter()
(3)Handler类
- 处理器的作用:决定日志输出到目的地
-
常用处理器类:
-
logging.StreamHandler 将日志信息输出到控制台
-
logging.hanlders.TimedRotatingFileHandler 将日志信息输出到文件,并支持按时间来切割
-
-
处理器类常用的方法:
-
设置日志的级别 handler.setLevel()
-
在处理器当中添加格式器 handler.setFormatter()
-
- 创建Formatter对象:formatter = logging.Formatter(fmt=None, datefmt=None, style='%')
- 说明:
- fmt:指定消息格式化字符串,如果不指定该参数则默认使用message的原始值
- datefmt:指定日期格式字符串,如果不指定该参数则默认使用"%Y-%m-%d %H:%M:%S"
- style:Python 3.2新增的参数,可取值为 '%', '{'和 '$',如果不指定该参数则默认使用'%'
(5)将日志信息同时输出到控制台和文件,封装成工具类
import logging.handlers
import time
class GetLogger:
logger = None
# 获取logger
@classmethod
def get_logger(cls):
if cls.logger is None:
# 获取 logger 日志器 并设置名称为“admin”
cls.logger = logging.getLogger("admin")
# 设置日志级别
cls.logger.setLevel(logging.INFO)
# 获取 控制台处理器
sh = logging.StreamHandler()
# 获取 文件处理器 根据时间分割
th = logging.handlers.TimedRotatingFileHandler(
filename="../log/{}.log".format(time.strftime("%Y_%m_%d %H_%M_%S")),
when="S",
interval=1,
backupCount=3,
encoding="utf-8")
# 设置 文件处理器 日志级别
th.setLevel(logging.ERROR)
# 获取 格式器
fmt = "%(asctime)s %(levelname)s [%(name)s] [%(filename)s %(funcName)s %(lineno)d] - %(message)s"
fm = logging.Formatter(fmt)
# 将 格式器 添加到 处理器
sh.setFormatter(fm)
th.setFormatter(fm)
# 将 处理器 添加到 日志器
cls.logger.addHandler(sh)
cls.logger.addHandler(th)
# 返回日志器
return cls.logger
if __name__ == '__main__':
logger = GetLogger.get_logger()
# 日志器应用
logger.info("这是info日志信息")
logger.debug("这是debug日志信息")
logger.warning("这是warning日志信息")
logger.error("这是error日志信息")
3、日志应用
日志应用:PO模式中,在base操作层、page对象层
-
base(在操作层文件中添加日志),以公共方法封装文件 base.py 为例
-
代码示例:
import time from time import sleep from selenium.webdriver.support.wait import WebDriverWait from day11_tpshop import page from day11_tpshop.base.get_logger import GetLogger # 获取log日志器 log = GetLogger().get_logger() class Base: def __init__(self, driver): log.info("[base:]正在获取初始化driver对象:{}".format(driver)) self.driver = driver # 查找元素方法 封装 def base_find(self, loc, timeout=30, poll=0.5): log.info("[base]:正在定位:{}元素,默认定位超时时间为:{}".format(loc, timeout)) # 使用显式等待 查找元素 return WebDriverWait(self.driver, timeout=timeout, poll_frequency=poll).until(lambda x: x.find_element(*loc)) # 点击元素方法 封装 def base_click(self, loc): log.info("[base]:正在对:{}元素执行点击事件".format(loc)) self.base_find(loc).click() # 输入元素方法 封装 def base_input(self, loc, value): log.info("[base]:正在获取:{}元素".format(loc)) # 获取元素 el = self.base_find(loc) log.info("[base]:正在对:{}元素执行清空操作".format(loc)) # 输入前 清空 el.clear() log.info("[base]:正在给{}元素输入内容:{}".format(loc, value)) # 输入 el.send_keys(value) # 获取文本信息方法 封装 def base_get_text(self, loc): log.info("[base]:正在获取{}元素文本值".format(loc)) return self.base_find(loc).text # 截图方法 封装 def base_get_img(self): log.info("[base]:断言出错,调用截图") self.driver.get_screenshot_as_file("../image/{}.png".format(time.strftime("%Y_%m_%d %H_%M_%S"))) # 判断元素是否存在方法 封装 def base_elememt_is_exist(self, loc): try: self.base_find(loc, timeout=2) log.info("[base]:{}元素查找成功,存在页面".format(loc)) return True # 代表元素存在 except: log.info("[base]:{}元素查找失败,不存在当前页面".format(loc)) return False # 代表元素不存在 # 回到首页(购物车、下订单、支付)都需要用到此方法 def base_index(self): # 暂停2秒 sleep(2) log.info("[base]:正在打开首页") self.driver.get(page.URL) # 切到frame表单方法 以元素属性切换 def base_switch_frame(self, element): log.info("[base]:正在切换到frame表单") self.driver.switch_to.frame(element) # 回到默认目录方法 def base_default_content(self): log.info("[base]:正在返回默认目录") self.driver.switch_to.default_content() # 切换窗口方法 def base_switch_to_window(self, title): log.info("正在执行切换title值为:{}窗口".format(title)) self.base_get_title_handle(title) # self.driver.switch_to.window(self.base_get_title_handle(title)) # 获取指定title页面的handle方法 def base_get_title_handle(self, title): # 获取当前页面所有的handles handles = self.driver.window_handles # 遍历handle for handle in handles: log.info("正在遍历handles:{}-->{}".format(handle, handles)) # 切换 handle self.driver.switch_to.window(handle) log.info("切换:{}窗口".format(handle)) # 获取当前页面title 并判断 是否等于 指定参数title log.info("条件成立!返回当前handle{}".format(handle)) if self.driver.title == title: # 返回 handle return handle
-
page(在对象层文件中添加日志):以登录为例,
page_login.py
-
代码示例:
from day11_tpshop import page from day11_tpshop.base.base import Base from day11_tpshop.base.get_logger import GetLogger # 获取log日志器 log = GetLogger().get_logger() class PageLogin(Base): # 点击 登录链接 def page_click_login_link(self): log.info("[page_login]:执行{}元素点击链接操作".format(page.login_link)) self.base_click(page.login_link) # 输入用户名 def page_input_username(self, username): log.info("[page_login]:对{}元素 输入用户名{}操作".format(page.login_username, username)) self.base_input(page.login_username, username) # 输入密码 def page_input_pwd(self, pwd): log.info("[page_login]:对{}元素 输入密码{}操作".format(page.login_pwd, pwd)) self.base_input(page.login_pwd, pwd) # 输入验证码 def page_input_verify_code(self, verify_code): log.info("[page_login]:对{}元素 输入验证码{}操作".format(page.login_verify_code, verify_code)) self.base_input(page.login_verify_code, verify_code) # 点击 登录 def page_click_login_btn(self): log.info("[page_login]:执行{}元素点击操作".format(page.login_btn)) self.base_click(page.login_btn) # 获取 错误提示信息 def page_get_err_info(self): return self.base_get_text(page.login_err_info) # 点击 错误提示框 确定按钮 def page_click_error_alert(self): log.info("[page_login]:执行{}元素点击操作".format(page.login_err_ok_btn)) self.base_click(page.login_err_ok_btn) # 判断是否登录成功 def page_if_login_success(self): # 注意 一定要将找元素的结果返回,True:存在 return self.base_elememt_is_exist(page.login_logout_link) # 点击 安全退出 def page_click_logout_link(self): self.base_click(page.login_logout_link) # 判断是否退出成功 def page_if_logout_success(self): return self.base_elememt_is_exist(page.login_link) # 组合业务方法 登录业务直接调用 def page_login(self, username, pwd, verify_code): log.info("[page_login]:正在执行登录操作,用户名:{},密码:{},验证码:{}".format(username, pwd, verify_code)) self.page_input_username(username) self.page_input_pwd(pwd) self.page_input_verify_code(verify_code) self.page_click_login_btn() # 组合登录业务方法 给(购物车模块、订单模块、支付模块)依赖登录使用 def page_login_success(self, username="13800001111", pwd="123456", verify_code="8888"): # 点击登录链接 self.page_click_login_link() log.info("[page_login]:正在执行登录操作,用户名:{},密码:{},验证码:{}".format(username, pwd, verify_code)) self.page_input_username(username) self.page_input_pwd(pwd) self.page_input_verify_code(verify_code) self.page_click_login_btn()