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
    

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Visual Studio 智能代码插件:CodeGeeX

前言 在软件开发领域,高效的编程助手一直是提升开发者效率和质量的关键。 随着人工智能技术的不断发展,智能编程助手逐渐成为开发者们不可或缺的工具。其中,CodeGeeX作为一款专为Visual Studio设计的免费智能编程助手,凭借其强大…

goimghdr,一个有趣的 Python 库!

更多Python学习内容:ipengtao.com 大家好,今天为大家分享一个有趣的 Python 库 - goimghdr。 Github地址:https://github.com/corona10/goimghdr 在图像处理和分析过程中,识别图像文件的类型是一个常见的需求。Python自带的imghdr…

AT32F415 使用embedded studio笔记

由于Embedded Studio还没有支持雅特力的支持包,因此通过MDK的工程无法直接导入到embedded studio中。需要自己新建一个工程。 新建的时候是可以选择雅特力的单片机的。 工程新建好后,默认会包含3个文件。如下图所示。其中两个汇编文件的作用是之前MDK的…

出现 Transaction rolled back because it has been marked as rollback-only 解决方法

目录 1. 问题所示2. 原理分析3. 解决方法1. 问题所示 用户反馈的Bug如下所示: Transaction rolled back because it has been marked as rollback-only截图如下: 浏览器终端同样显示: 2. 原理分析 错误表明,在事务的生命周期内,遇到了某个异常或条件,导致该事务被标记…

Vue3学习使用axios和qs进行POST请求和响应处理

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、前言1.准备工作2.发送POST请求3.处理响应数据4.总结 一、前言 在前端开发中,经常需要与后端进行数据交互,其中包括发送POST请求并处理响…

2024年中国金融行业网络安全市场全景图

网络安全一直是国家安全的核心组成部分,特别是在金融行业,金融机构拥有大量的敏感数据,包括个人信息、交易记录、财务报告等,这些数据的安全直接关系到消费者的利益和金融市场的稳定,因此金融行业在网络安全建设领域一…

【机器学习】利用机器学习优化陆军战术决策与战场态势感知

🔒文章目录: 💥1.引言 🛴2.机器学习在陆军战术决策中的应用 🛣️2.1数据收集与预处理 🌄2.2模型构建与训练: 🌅2.3实时决策支持: 🌅2.4代码实现 &…

Genzai:一款针对物联网安全的多功能实用性工具套件

关于Genzai Genzai是一款针对物联网安全的多功能实用性工具套件,该工具旨在识别与物联网相关的仪表盘,并扫描它们以查找默认密码和安全问题,广大研究人员可以使用该工具来检测和提升物联网设备的安全性。 Genzai支持用户以输入的形式提供一个…

电子围栏(地理围栏)设计逻辑

做完整的项目时需要考虑安全问题,判断车辆在不该出现的位置出现时自动刹车。 只能说可以有吧。 地理围栏的概念 自动驾驶地理围栏是指在自动驾驶系统中定义的一种虚拟边界,用于限制车辆的运行范围。地理围栏可以通过全球定位系统(GPS&#…

nginx设置一个TCP代理(用于RDP连接)

在 Nginx 中,stream 上下文必须在 http 上下文之外,并且只能位于顶级配置文件中或包含在主配置文件中的单独文件中。 Nginx 的配置文件通常包含一个 http 块,用于处理 HTTP 和 HTTPS 请求,但是 stream 块是独立的,并且…

Acrobat Pro DC 2024 Mac软件安装包下载PDF2024 Mac安装教程

安装 步骤 1,双击打开下载好的安装包。 2,选择acrobat dc installer.pkg双击启动安装程序。 3,点击继续。 4,点击继续。 5,点击继续。 6,点击安装。 7,输入电脑密码。 8,软件安装中…

香橙派 AIpro开发板初上手

一、香橙派 AIpro开箱 最近拿到了香橙派 AIpro(OrangePi AIpro),下面就是里面的板子和相关的配件。包含主板、散热组件、电源适配器、双C口电源线、32GB SD卡。我手上的这个是8G LPDDR4X运存的版本。 OrangePi AIpro开发板是一款由香橙派与华…

JAVA学习·String类的常用方法

String 类及其创建 String 类的创建 String 类是 Java 内置的一个类,其完全限定类名是java.lang.String。想要创建一个字符串有多重方式,比如创建字符串"Hello": String s1 "Hello"; // 字面量创建 String s2 new St…

linux部署rustdesk

1.拉取RustDesk镜像 sudo docker image pull rustdesk/rustdesk-server2.启动hbbs服务 sudo docker run --name hbbs -p 21115:21115 -p 21116:21116 -p 21116:21116/udp -p 21118:21118 -v pwd:/root -td --nethost rustdesk/rustdesk-server hbbs3.启动hbbr服务 sudo dock…

如何从Android恢复已删除的文件?3 种有效的方式

有时我们可能会错误地删除Android设备上的重要文件。更疯狂的是,Android手机上的文件在一夜之间消失了,我们不知道为什么。我们感到非常遗憾和恼火,但不知道。但是,此时学习如何从Android手机恢复已删除的文件为时已晚&#xff0c…

Mesa Gallium框架入门初探

Mesa Gallium框架入门初探 MESA Gallium框架 MESA源码里面有2套架构,现在驱动主要基于Gallium架构。 这里我们重点来看看Gallium架构: 经典架构 Gallium架构 Gallium展开 Gallium中主要包含下面几块: Auxiliary模块:一些公共函数或者辅助…

Word如何绘制三线表及设置磅值

插入表格, 开始 边框 边框和低温 设置磅值 先全部设置为无边框 上边 1.5 0.5 以上内容未完善,请等待作者更新

内网权限提升

打点进入内网中,权限一般为 web 服务的权限 1、什么是提权 一般一来说是低权限用户去申请高权限用户,可以是(配置不当、溢出类漏洞(历史漏洞)、本地漏洞) 2、常见用户分类 windows: 本地登录…

使用 Orange Pi AIpro开发板基于 YOLOv8 进行USB 摄像头实时目标检测

简介 官网:Orange-Pi-AIpro 算力指标与概念 TOPS是每秒数万亿或万亿次操作。它主要是衡量可实现的最大吞吐量,而不是实际吞吐量的衡量标准。大多数操作是 MAC(multiply/accumulates),因此: TOPS &#xf…

干货!渗透测试入门教程!(建议收藏)

渗透测试是指从内网、外网等网络环境中,利用各种手段对某个特定网络进行模拟攻击,目的是为了寻找可能被利用的漏洞,是企业中重要的一环、 虽然大多数人在学习后都能快速上手,但渗透测试还是有一定的门槛,今天就给大家…