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

news2024/11/16 3:39:31

断言

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
    

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1705320.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI大模型实现德语口语练习

利用AI大模型实现德语口语练习的应用需要整合多种技术和资源,以确保学生能够获得全面、互动和有效的学习体验。以下是实现德语口语练习应用的详细流程和技术要点。北京木奇移动技术有限公司,专业的软件外包开发公司,欢迎交流合作。 实现流程 …

latex中复制到word里面之后如何转变成word自带的公式

详细步骤如下: 第一步,将latex中的公式复制到word里面,例如:$r_1^d$ 第二步,选中$$里面的部分,也就是去掉$$,选中剩余的部分,例如:r_1^d 第三步,word工具栏里…

【招聘】易基因科技诚聘销售总监 虚位以待

🚀 关于我们 易基因拥有一支充满活力的科研服务团队,致力于以“引领表观遗传学科学研究与临床应用”为愿景,依托高通量测序技术和云数据分析平台,为医疗机构、科研机构、企事业单位等提供以表观遗传学技术为核心的多组学科研服务…

【高阶数据结构(七)】B+树, 索引原理讲解

💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:高阶数据结构专栏⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习更多数据结构   🔝🔝 高阶数据结构 1. 前言2. B树讲解…

3070ti和4060ti哪个好

GeForce RTX 3070 Ti和RTX 4060 Ti主要在显存类型、运行频率和性能表现等方面有所区别。具体分析如下: 显存类型 GeForce RTX 3070 Ti:搭载了8GB GDDR6X显存,显存速度为19Gbps,显存位宽为256 bit。GeForce RTX 4060 Ti&#xff1…

Apache Doris 基础 -- 数据表设计(数据模型)

Versions: 2.1 1、模型概览 本主题从逻辑角度介绍了Doris中的数据模型,以便您可以在不同的业务场景中更好地使用Doris。 基本概念 本文主要从逻辑的角度描述Doris的数据模型,旨在帮助用户在不同的场景更好地利用Doris。 在Doris中,数据在…

【STL】C++ list 基本使用

目录 一 list 常见构造 1 空容器构造函数(默认构造函数) 2 Fill 构造函数 3 Range 构造函数 4 拷贝构造函数 二 list迭代器 1 begin && end 2 rbegin && rend 三 list 容量操作 四 list 修改操作 1 assign 2 push_front &a…

【RuoYi】如何启动RuoYi项目

一、前言 最近,在做一个管理系统的项目,接触到了RuoYi这个前后端分离的框架,自己是第一次接触这个框架,所以刚开始有点好奇,在用该框架写了一些代码后。发现RuoYi这个框架做的真的好,它包含了权限管理和一些…

Petalinux 制作ZYNQ镜像文件流程

1概述 在Zynq-7000 SoC中搭建运行Linux,嵌入式软件栈。 处理器系统引导是一个分两个阶段的过程。第一个阶段是一个内部 BootROM,它存储 stage-0 的引导代码。BootROM 在 CPU 0 上执行,CPU 1 执行等待事件(WFE)指令。…

WordPress|子比主题美化-给首页左侧添加联系站长按钮

WordPress子比主题美化-给首页左侧添加联系站长按钮 5ccy.cn 我创创业-副业资源整合网-网络赚钱-网络创业-资源分享 http://5ccy.cn 效果如下: 功能介绍 联系站长图标的作用主要是为用户提供一种便捷的方式,以与网站的管理员或站长取得联系。这个图标一般放置在网…

cocos creator做圆形进度条

效果图: 我们在开发过程中经常要用到圆形进度条,例如技能CD 原文链接 之前写了一篇cocos2dx-lua_ProgressTimer创建扇形进度条,这里简单记录下在cocosCreator中如何制作。 具体方法 cocosCreator做起来比2dx还是要简单很多,首先给节点添加p…

Java 类加载机制解密一探到底

类加载是 Java 程序在运行期执行之前的重要环节,它决定着程序的运行效率和稳定性。本文将为您深入剖析 Java 类加载机制的整个生命周期,揭开神秘面纱,让您彻底掌握这一核心知识点。 一、类的生命周期概述 类的生命周期在Java中指的是从类被加…

大疆mic、罗德、西圣无线麦克风怎么选?大疆、西圣麦克风测评对比

如今是一个短视频飞速发展的时代,越来越多自媒体人通过短视频的方式来进行直播带货、生活Vlog、线上K歌等,记录下生活里种种美丽的瞬间。不过一个好的视频除了要有巧妙的构思和清晰稳定的拍摄外,干净的声音也是必不可少的部分。短视频归根结底…

飞控如何和接收机接线?

飞控如何和接收机接线? 一般遥控都是按照顺序1对1接到飞控的INPUT端口。特别注意,华科尔的接收机,需要把1和2通道条换过来。 具体方法如下: 下面以MC6遥控接收机为例子: 用下面的图的接收机连接线来演示&#xff1a…

06.部署jpress

安装mariadb数据 yum -y install mariadb-server #启动并设置开启自启动 systemctl start mariadb.service systemctl enable mariadb.service数据库准备 [rootweb01 ~]# mysql Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id…

React-入门

React由Meta公司研发,是一个用于构建Web和原生交互界面的库 既可以写基于浏览器的应用,还可以写苹果和安卓的原生应用 优势 开发环境搭建 create-react-app是一个快速创建React开发环境的工具,底层是由Webpack构建,封装了配置细…

SAP后续借记、后续贷记、贷方凭证的应用介绍

SAP-MM模块中发票校验MIRO,对于做采购或财务相关的用户都应该非常熟悉,可能每天都需要进行这业务操作处理,但是在发票校验的系统界面中,有三个使用不是很频繁的功能(如下图红色框)。 对于这三业务功能曾听有些用户抱怨SAP怎么那么麻烦啊,不就是补偿或扣供应商的钱嘛,我…

Bookie存储架构源码剖析|得物技术

一、Pulsar存储架构简析 Pulsar作为新一代MQ中间件,在底层架构设计上充分贯彻了存算分离的思想,broker与Bookeeper两个组件独立部署,前者负责流量的调度、聚合、计算,后者负责数据的存储,这也契合了云原生下k8s大行其…

【ARM+Codesys案例】树莓派+Codesys软PLC方案在包装行业灌装旋盖机的应用

ARM系列支持:全志T3、RK3568、树莓派 机型定义:双工位旋盖机 旋盖机主要适用于不同规格的材质及不同规格的盖、旋(轧)盖。适用螺旋盖、防盗盖、防撞盖、压入盖等。压力可方便调整,根据瓶盖大小设置取盖位。结构紧凑、…

Java基础入门day56

day56 现有问题 之前的servlet中,服务器通过Servlet响应客户端页面的不足: 开发方式麻烦:继承父类或者实现接口,覆盖方法,配置注册 代码修改麻烦:一旦代码修改,需要重新编译、部署、重启服务 …