当前位置: 首页 > news >正文

web自动化的断言和日志封装

断言

UI自动化常见的断言条件包括:

  • 通过当前页面的URL地址
  • 通过当前页面的标题
  • 通过当前页面的提示文本信息
  • 通过当前页面的某些元素变化/显示

一句话总结:通过肉眼观察页面的变化检查。 【用代码模仿人的识别页面】

  • 一般断言写一条就够了,如果业务要求比较严谨,可以写多条;
  • 如果写了多条,那么每一条断言都通过 才是用例执行通过了。

登录用例的断言:

  • 1、首页欢迎提示信息
  • 2、首页的登录用户名显示

那么这些断言的元素定位和操作,也要封装到page_object中去。【这两个都 在home_page里】

from selenium.webdriver.common.by import By
from common.basepage_v1 import BasePage
class HomePage(BasePage):
#属性 登录链接
login_link_locator = (By.LINK_TEXT, '登录')
# 欢迎提示信息
welcome_tips_locator = (By.XPATH, '//span[text()="欢迎来到柠檬
班"]')
# 用户名
username_text_locator = (By.XPATH, '//a[@class="link-name"]')
# 操作->元素行为,登录操作
def click_login_link(self):
"""点击登录链接"""
self.wait_element_clickable(self.login_link_locator).click()
def is_dispaly_weltext(self):
"""欢迎语检查 返回文本
is_dispaly(): 元素是否存在,存在返回True 不存在返回False
"""
return self.is_display(self.welcome_tips_locator) # 直接调
用basepage里公告方法
def get_username(self):
"""获取用户名"""
return self.get_text(self.username_text_locator)

然后可以在测试用例里加上断言的代码:

  • 注意: 一个用例可以添加多条断言, 测试通过的条件:所有的断言都需 要通过,有一条断言失败的,那么测试就是不通过
    from page_object.login_page import LoginPage
    from page_object.home_page import HomePage
    from selenium import webdriver
    # pytest框架编写测试用例
    def test_login():
    driver = webdriver.Chrome()
    driver.maximize_window()
    driver.get("http://mall.lemonban.com:3344/")
    # 1、点击homepage 登录的链接 == 先实例化对象,再调用实例方法,实例
    方法要传参driver
    HomePage(driver).click_login_link()
    # 2、调用LoginPage里的login实例方法 执行登录操作== 先实例化对象,
    再调用实例方法,实例方法要传参
    LoginPage(driver).login("lemon_py","12345678")
    # 断言机制检查测试是否通知(预期结果+实际结果)
    # 1、首页欢迎提示信息
    assert HomePage(driver).is_dispaly_weltext() # 断言元素是否存在
    结果True /False 可以不写。
    # 2、首页的登录用户名
    assert HomePage(driver).get_username() == "lemon_py"

    其他的用例也可以加上同样的断言。

  • 框架继续优化: 前置后置

  • 这个打开浏览器获取driver 每个用例都需要, 并且每个用例执行完后,需要关闭浏览器; 我们可以定义一个夹具: 设置前置和后置操作 避免代码的重复性。

    import pytest
    from selenium import webdriver
    from loguru import logger
    @pytest.fixture
    def open_browser_url():
    driver = webdriver.Chrome()
    driver.maximize_window()
    driver.get('http://mall.lemonban.com:3344/')
    yield driver
    # 后置-关闭浏览器
    driver.quit()
    

    然后所有的测试用例里都可以调用这个前置,简化代码。

注意:关于所有测试用例运行期间只打开/关闭一次浏览器,不可取:

  • UI自动化因为页面不太稳定,所以建议不要所有用例打开一次浏览器 关闭 一次浏览器;
  • 比如中间有某个用例失败了,那么就会导致后面的用例也失败了。
  • 所以每 条测试用例之间最好是独立的。 所以我们每个用例里都独立打开一次浏览器和关闭浏览器操作,可以避免很 多的问题。

basePage的是不会变化的,每个项目都可以通用的

pageobject里的是会变化的 每个项目的页面不一样,定位元素的和操作 也会不一样

testcase也会变化的,每个项目的用例不一样的。

夹具层: 基本上【除了地址】也是不变的

数据层: 变化的 每个项目要求的测试数据不一样的

日志 + 异常捕获封装: 对框架的优化

1、执行用例的过程中,没有日志 不方便定位,所以我们在一些关键的步骤里 加上日志记录。

  • 在basepage和pageobject里各个方法都加上日志,记录做了什么事情

2、有些地方可能会出现错误,比如元素没有定位到,所以我们需要对这些可能 发生异常的地方加上异常捕获。在用例执行报错的时候也应有对应的报错日志 记录

思考:代码执行时候在什么地方会发生异常??

元素定位 (NoSuchElementException/TimeoutException):

  • basepage里三种显示等待的方法,每个元素定位都用,元素定位 失败了,异常捕获记录日志,
  • 因为元素都没有找到,就没有必要继续执行后面的代码了。-抛出 错误 代码终止运行 raise抛出

元素操作: 点击,鼠标,输入等操作虽然发生错误比较少,但是比如 有些点击失败了,也要记录日志,做异常捕获。

  • 可以做异常捕获,但是因为发生错误比较少,我们也可以不做。 这里我们就简化一些。要加的 大家可以自行加上。

断言(AssertionError): 断言也可以经常会发生错误的,也肯定要做 异常捕获和日志的

  • 断言成功记录日志
  • 断言失败,记录日志,然后raise报错信息。
    def wait_element_clickable(self, locator):
     logger.info(f"等待元素{locator}可以点击")
     try:
        web_element=WebDriverWait(self.driver,8,0.5).until(EC.element_to_be_clickable(locator))
     except Exception as e:
         logger.error(f"等待元素超时{e}")
         raise e
         return web_element

元素定位和操作都加上了日志,但是断言没有加。而且断言也 没有做异常处理。

断言是一个自带的关键字,没有办法直接加日志和异常处理,如果直接在用例 里做,那么太麻烦了,每条用例都要写一遍。

  • 所以要把断言的方法进行封装,封装一次,多次调用。== 封装的函数里 做异常捕获 + 日志封装
  • 断言是每条用例都要用的公共方法,所以我们把它封装放在common里。

我们前面讲过,断言的常见几种方式:

  • 比较相等: assert a == b
  • 比较大小(大于/小于/大于等于/小于等于): assert a > b
  • 内容包含/内容不包含:assert a in b
  • 验证表达式是否为真: assert condition

所以这个断言封装里最好包含这些所有的情况:

  • 这里单独封装了3个函数,如果后面还有其他的断言方法 可以再丰富进去。
  • 在每个函数里加上日志 + 异常捕获
    from loguru import logger
    #预期与实际进行比较
    def assert_equals(actual, excepted):
     try:
         assert actual == excepted
         logger.info(f'断言成功,预期结果:【{excepted}】,实际结
    果:【{actual}】')
     except Exception as e:
         logger.error(f'断言失败,预期结果:【{excepted}】,实际结
    果:【{actual}】')
         raise e
    #str1是否在str2里面
    def assert_in(str1, str2):
     try:
         assert str1 in str2
         logger.info(f'断言成功,【{str1}】在【{str2}】里面的')
     except Exception as e:
         logger.error(f'断言失败,【{str1}】在【{str2}】里面的')
         raise e
    #表达式是否为真
    def assert_condition(condition):
     try:
         assert condition
         logger.info(f'断言成功,【{condition}】为真')
     except Exception as e:
         logger.error(f'断言失败,【{condition}】为假')
         raise e
    

    所有的测试用例里都可以优化替换为这个断言的封装函数。成功和失败了 就可以看到日志。

相关文章:

  • 计算机体系结构期末快速复习
  • numpy向量的转置与向量相乘
  • 【大模型】 基于AI和全球化进程的权衡:开源大模型与闭源大模型
  • 『大模型笔记』从基础原理出发提升深度学习性能
  • docker部署kafka实战
  • SpringBoot自定义starter
  • 软件无线电学习-第二代移动通信系统过程理解
  • 【计算机网络】第三章——回退N帧协议
  • 上海亚商投顾:沪指震荡反弹 半导体产业链午后爆发
  • Golang | Leetcode Golang题解之第109题有序链表转换二叉搜索树
  • 层次式架构设计理论与实践
  • 初学C语言100题:经典例题节选(源码分享)
  • Moto和Inter字节序
  • 【讲解下Web前端三大主流的框架】
  • 2024爆款神器!会声会影2024旗舰版,让你的视频制作技能暴涨,不学真的亏大了!
  • 中国科技期刊卓越行动计划重点期刊
  • 推导2维镜像变换(Reflection Transform)的公式
  • 数据集007:垃圾分类数据集(含数据集下载链接)
  • 宝塔部署纯Vue项目,无后端
  • 文献分享《Microbiome and cancer》
  • 十四届全国人大常委会举行第四十三次委员长会议 ,听取有关草案和议案审议情况汇报
  • 江西省国资委原副主任李键主动向组织交代问题,接受审查调查
  • 国家发改委答澎湃:将建立和实施育儿补贴制度,深入实施提振消费专项行动
  • 一张老照片里蕴含的上海文脉
  • 荣盛发展去年亏损约84.43亿元,要“过苦日子、紧日子”
  • 央视曝光假进口保健品:警惕!保税仓发货不等于真进口