web自动化测试之日志收集

1、logging模块

logging python 自带的日志收集模块
常见的日志级别:  DEBUGINFOWARNINGERRORCRITICAL

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()
(4)Formatter类
  • 创建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()

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值