首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >封装基本函数「执行日志、异常处理、失败截图」

封装基本函数「执行日志、异常处理、失败截图」

作者头像
清菡
发布2020-12-02 15:30:04
发布2020-12-02 15:30:04
1.4K0
举报
文章被收录于专栏:清菡软件测试清菡软件测试

封装基本函数-执行日志、异常处理、失败截图

1.任何元素操作之前一定要等待,操作任何一个元素之前都要等到它出现,然后再去操作它,否则会遇到报错,元素找不到。页面的某一个操作导致页面发生变化的时候,就必须要等,等到元素出现,再去使用。

2.一个用例执行失败,但是整个运行过程不应该结束。所以,放在其它服务器上,我们分析问题的时候需要日志和测试报告。自动生成测试报告以及执行日志。执行日志需要打印出来,里面每一点每一点都在干什么。如果有报错,错误信息也应该显示在日志里面。Web自动化涉及页面操作,如果有报错,还需要有截图。通过看截图可以看到问题在哪。

比如login用例中的每一步是页面对象的方法来执行的,要保证任何一行代码执行失败,都能找到这样一个报错并截图,以及对应的报错信息放在日志中。异常需要抛出,它失败了,意味着测试用例失败了。

3.在每个页面对象的每一个方法中都加try except,用例的断言加try except,但是这样很冗余,我们怎样更好得解决呢?

在自己的业务函数中调用的都是selenium webdriver中的基本函数。大部分的操作都是等待、点击、输入,当然还有下拉列表处理、窗口处理等等,既然所有的方法都是基于这些基本操作。

click() find_element wait .text get_attribute,先单独对这些函数都做一些异常处理,对这些基本函数都做到了异常处理日志输出,所有这些地方来调用它的都能做到了。

4.basepage可以放一些公共的方法。

basepage对日志、异常处理、截图进行了处理。

5.希望看到这个截图的时候,一看就知道是哪个页面,哪个地方截的图。如果所有的截图文件都是一个名字,那看到的只有最后一次截图,其它都被覆盖了。框架当中要截图,图片名称要非常得到位就行。

6.save_screenshot是有截屏操作的。只截图浏览器当中当前页面的内容,浏览器以外的内容都截图不了。比如上传窗口就是截图不到的。通过按键方式进行全屏截取,Python库中也有截取整个屏幕的函数调用。

这里只用截取html页面就行了。看save_screenshot的源码解释:

代码语言:javascript
复制
 return self.get_screenshot_as_file(filename)

就是存储为文件的意思。

6.是基本操作会来调用截屏。在页面的某一个具体操作行为当中才会调用等待。wait_eleVisible知道到底当前是哪个模块,哪个页面,哪个操作。谁调它,谁就传值。所以需要传递一个参数,把这个参数给到截屏。

7.实际过程中,你自己写的框架,理论上来说只适用于当前你的项目的,项目的差异性是非常大的。如果别人问你,你的框架有什么可以改进的空间?只能说目前做的框架对以前的项目是完全够用的,未来在工作过程中遇到什么问题,再去考虑扩展。

8.断言中没有做异常捕获,不捕获也没关系,断言失败的详情会在测试日志中体现的比较明显。

代码

来自Common文件夹下的basepage.py文件

代码语言:javascript
复制
from Common import logger
import logging
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import datetime
import time

from Common.dir_config import screenshot_dir

class BasePage:

    # 包含了PageObjects当中,用到所有的selenium底层方法。
    # 还可以包含通用的一些元素操作,如alert,iframe,windows...
    # 还可以自己额外封装一些web相关的断言
    # 实现日志记录、实现失败截图

    def __init__(self,driver):
        self.driver = driver

    def wait_eleVisible(self,loc,img_doc="",timeout=30,frequency=0.5):
        logging.info("等待元素 {} 可见。".format(loc))
        try:
            # 起始等待的时间 datetime
            start = datetime.datetime.now()
            WebDriverWait(self.driver,timeout,frequency).until(EC.visibility_of_element_located(loc))
            # 结束等待的时间
            end = datetime.datetime.now()
            logging.info("开始等待时间点:{},结束等待时间点:{},等待时长为:{}".
                format(start,end,end-start))
        except:
            # 日志
            logging.exception("等待元素可见失败:")
            # 截图 - 哪一个页面哪一个操作导致的失败。+ 当前时间
            self.save_web_screenshot(img_doc)
            raise

    # 查找一个元素
    def get_element(self,loc,img_doc=""):
        """
        :param loc: 元素定位。以元组的形式。(定位类型、定位时间)
        :param img_doc: 截图的说明。例如:登陆页面_输入用户名
        :return: WebElement对象。
        """
        logging.info("查找 {} 中的元素 {} ".format(img_doc,loc))
        try:
            ele = self.driver.find_element(*loc)
            return ele
        except:
            # 日志
            logging.exception("查找元素失败")
            # 截图
            self.save_web_screenshot(img_doc)
            raise

    def click_element(self,loc,img_doc,timeout=30,frequency=0.5):
        """
        实现了,等待元素可见,找元素,然后再去点击元素。
        :param loc:
        :param img_doc:
        :return:
        """
        # 1、等待元素可见
        self.wait_eleVisible(loc,img_doc,timeout,frequency)
        # 2、找元素
        ele = self.get_element(loc,img_doc)
        # 3、再操作
        logging.info(" 点击元素 {}".format(loc))
        try:
            ele.click()
        except:
            # 日志
            logging.exception("点击元素失败")
            # 截图
            self.save_web_screenshot(img_doc)
            raise

    # 文本输入
    def input_text(self,loc,img_doc,*args):
        # 1、等待元素可见
        self.wait_eleVisible(loc,img_doc)
        # 2、找元素
        ele = self.get_element(loc,img_doc)
        # 3、再操作
        logging.info(" 给元素 {} 输入文本内容:{}".format(loc,args))
        try:
            ele.send_keys(*args)
        except:
            # 日志
            logging.exception("元素输入操作失败")
            # 截图
            self.save_web_screenshot(img_doc)
            raise

    # 获取元素的属性值
    def get_element_attribute(self,loc,attr_name,img_doc):
        ele = self.get_element(loc,img_doc)
        # 获取属性
        try:
            attr_value =  ele.get_attribute(attr_name)
            logging.info("获取元素 {} 的属性 {} 值为:{}".format(loc, attr_name,attr_value))
            return attr_value
        except:
            # 日志
            logging.exception("获取元素属性失败")
            # 截图
            self.save_web_screenshot(img_doc)
            raise

    # 获取元素的文本值。
    def get_element_text(self,loc,img_doc):
        ele = self.get_element(loc, img_doc)
        # 获取属性
        try:
            text = ele.text
            logging.info("获取元素 {} 的文件值为:{}".format(loc, text))
            return text
        except:
            # 日志
            logging.exception("获取元素文本值失败")
            # 截图
            self.save_web_screenshot(img_doc)
            raise



    # 实现网页截图操作
    def save_web_screenshot(self,img_doc):
        #  页面_功能_时间.png
        now = time.strftime("%Y-%m-%d %H_%M_%S")
        filepath = "{}_{}.png".format(img_doc,now)
        try:
            self.driver.save_screenshot(screenshot_dir +"/" + filepath)
            logging.info("网页截图成功。图片存储在:{}".format(screenshot_dir +"/" + filepath))
        except:
            logging.exception("网页截屏失败!")


# windows切换

# iframe切换

# select下拉列表

# 上传操作 - 

PageObjects文件夹下的index_page.py文件

代码语言:javascript
复制

from Common.basepage import BasePage
from PageLocators.indexPage_locator import IndexPageLocator as loc
import time

class IndexPage(BasePage):


    # 检测昵称是否存在
    def check_nick_name_exists(self):
        """
        :return: 存在返回True,不存在返回False
        """
        self.wait_eleVisible(loc.about_us,"首页_等待关于我们元素出现")
        time.sleep(0.5)
        try:
            self.get_element(loc.user_link,"首页_找用户昵称元素")
            return True
        except:
            return False

    # 点击投标按钮
    def click_invest_button(self):
        self.click_element(loc.bid_button,"首页_点击第一个抢投标按钮")

PageObjects文件夹下的bid_page.py文件

代码语言:javascript
复制

from PageLocators.bidPage_locator import BidPageLocator as loc
from Common.basepage import BasePage


class BidPage(BasePage):

    # 投资
    def invest(self,money):
        # 在输入框当中,输入金额
        self.input_text(loc.money_input,"标页面_金额输入框",money)
        self.click_element(loc.invest_button,"标页面_提交投资操作")


    # 获取用户余额
    def get_user_money(self):
        self.wait_eleVisible(loc.money_input,"标页面_获取用户余额")
        return self.get_element_attribute(loc.money_input,"data-amount","标页面_获取用户余额")


    # 投资成功的提示框 - 点击查看并激活
    def click_activeButton_on_success_popup(self):
        self.click_element(loc.active_button_on_successPop,"标页面_投资成功的提示框 - 点击查看并激活")


    # 错误提示框 - 页面中间
    def get_errorMsg_from_pageCenter(self):
        self.wait_eleVisible(loc.invest_failed_popup,"标页面_投资失败提示框 - 提示信息获取")
        msg = self.get_element_text(loc.invest_failed_popup,"标页面_投资失败提示框 - 提示信息获取")
        self.click_element(loc.invest_close_failed_popup_button,"标页面_关闭投资失败提示框")
        return msg

    # 获取提示信息 - 投标按钮上的
    def get_errorMsg_from_investButton(self):
        pass

文件目录:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 清菡软件测试 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 封装基本函数-执行日志、异常处理、失败截图
  • 代码
    • 文件目录:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档