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

技术分享 | app自动化测试(Android)-- 属性获取与断言

断言是 UI 自动化测试的三要素之一,是 UI 自动化不可或缺的部分。在使用定位器定位到元素后,通过脚本进行业务操作的交互,想要验证交互过程中的正确性就需要用到断言。

常规的UI自动化断言

分析正确的输出结果,常规的断言一般包含以下的几个情形:

  • 比较大小

  • 包含或者不包含

  • 验证布尔值

Python 示例代码
# 第一种 :比较大小
price = driver.find_element(By.XPATH,'//*[contains(@resource-id="current_price")]').text
assert float(price) >=170# 第二种 :包含验证
name = driver.find_element(By.XPATH,'//*[contains(@resource-id="stockName")]').text
assert "BABA" in name# 第三种 :布尔值验证
def check():name = driver.find_elements(By.XPATH,'//*[contains(@resource-id="stockName")]')return True if len(name)!=0 else False
assert check()

上面的示例可以看出,Python 的 assert 是用来判断一个条件是否为真,如果它为真,就继续执行,如果为假,则抛出 AssertError 并且包含错误信息。断言可以在条件不满足程序运行的情况下直接返回错误。

Java 示例代码
// 第一种 :比较大小
String price = driver.findElement(By.xpath("//*[contains(@resource-id=\"current_price\")]")).getText();
float currentprice = Float.parseFloat(price);
float expectprice = 170;
assert currentprice >= expectprice;// 第二种 :包含验证
String name = driver.findElement(By.xpath("//*[contains(@resource-id=\"stockName\")]")).getText();assert name.contains("BABA");// 第三种 :布尔值验证
@Test
public boolean check(){List<WebElement> names = driver.findElements(By.xpath("//*[contains(@resource-id=\"stockName\")]"));return names.size() > 0 ? true : false;
}@Test
public void checkTest(){assert check();
}

上面的示例可以看出,测试中经常会需要使用断言来判断一个条件是否为真,Java 语法中也可以通过 assert 关键字进行断言。另外如果需要更复杂的断言处理,可以使用 Hamcrest 提供的方法,Hamcrest 提供了大量被称为“匹配器”的方法。

Hamcrest断言

Hamcrest 是一个以测试为目的,能组合成灵活表达式的匹配器类库,用于编写断言的框架,使用这个框架编写断言,可以提高可读性以及开发测试的效率。Hamcrest 提供了大量被称为“匹配器”的方法。每个匹配器都设计用于执行特定的比较操作。Hamcrest 的可扩展性强,允许创建自定义的匹配器,并支持多种语言。

Hamcrest 安装
  • Python 版本

pip install pyhamcrest

  • Java 版本
<dependency><groupId>org.hamcrest</groupId><artifactId>hamcrest</artifactId><version>2.2</version><scope>test</scope>
</dependency>
Hamcrest 导包
  • Python 版本

from hamcrest import *

  • Java 版
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

Hamcrest 提供了一个全新的断言语法(assert_that),可以只使用 assert_that 一个断言语句,结合 Hamcrest 提供的匹配符,就可以完成各种断言场景。

常用方法 API

1.比较两个字符串相等,示例代码如下:

  • Python 版本

assert_that("this is a string",equal_to("this is a string"))

  • Java 版本

assertThat("this is a string",equalTo("this is a string"));

2.数值匹配,比较两个值是否接近,示例代码如下:

  • Python 版本

assert_that(8,close_to(10,2))

  • Java 版本

assertThat(8.0,closeTo(10,2));

解释:断言 8 接近于 (8 ~ 12)这个范围。

3.包含某个字符,示例代码如下:

  • Python 版本

assert_that('abc',contains_string('d'))

  • Java 版本

assertThat("abc",containsString("d"));

案例

使用“雪球”应用,打开雪球 APP,点击页面上的搜索输入框输入“alibaba”,然后在搜索联想出来的列表里面点击“阿里巴巴”,选择股票分类,获取股票类型为“09988”的股票价格,最后验证价格在预期价格的 10% 范围浮动。核心代码如下:

PYTHON 版本
from hamcrest import assert_that, close_to
...
def test_wait(self):# 点击搜索输入框self.driver.find_element_by_id("com.xueqiu.android:id/tv_search").click()# 输入 “alibaba”self.driver.find_element_by_id("com.xueqiu.android:id/search_input_text").send_keys("alibaba")# 点击“阿里巴巴”self.driver.find_element_by_xpath("//*[@text='阿里巴巴']").click()# 点击“股票”self.driver.find_element_by_xpath("//*[contains(@resource-id,'title_container')]//*[@text='股票']").click()# 获取股票价格locator = (MobileBy.XPATH,"//*[@text='09988']/../../..\//*[@resource-id='com.xueqiu.android:id/current_price'")ele = WebDriverWait(self.driver,10)\.until(expected_conditions.element_to_be_clickable(locator))print(ele.text)current_price = float(ele.text)expect_price = 170# 使用 hamcrest 断言来判断股票价格浮动在 10% 范围内assert_that(current_price,close_to(expect_price, expect_price*0.1))
...
JAVA 版本
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
...
@Test
public void wait1Test(){// 点击搜索输入框driver.findElementById("com.xueqiu.android:id/tv_search").click();// 输入 “alibaba”driver.findElementById("com.xueqiu.android:id/search_input_text").sendKeys("alibaba");// 点击“阿里巴巴”driver.findElementByXPath("//*[@text=\"阿里巴巴\"]").click();// 点击“股票”driver.findElementByXPath("//*[contains(@resource-id,\"title_container\")]//*[@text=\"股票\"]").click();// 获取股票价格By price_locator = By.xpath("//*[@text='09988']/../../..//*[@resource-id=\"com.xueqiu.android:id/current_price\"]");WebDriverWait wait = new WebDriverWait(driver, 10);WebElement ele = wait.until(ExpectedConditions.elementToBeClickable(price_locator));System.out.println(ele.getText());double currentPrice = Double.parseDouble(ele.getText());double expectPrice = 170;// 使用 hamcrest 断言来判断股票价格浮动在 10% 范围内assertThat(currentPrice, closeTo(expectPrice,expectPrice*0.1));}
...

上面的示例中,通过assert_that/assertThat 是用于生成测试断言的样式化语句,比较两个值(current_price 与 expect_price)是否接近,断定实际值 current_price 在expect_price-expect_price0.1 与 expect_price+expect_price0.1 范围区间浮动。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

相关文章:

技术分享 | app自动化测试(Android)-- 属性获取与断言

断言是 UI 自动化测试的三要素之一&#xff0c;是 UI 自动化不可或缺的部分。在使用定位器定位到元素后&#xff0c;通过脚本进行业务操作的交互&#xff0c;想要验证交互过程中的正确性就需要用到断言。 常规的UI自动化断言 分析正确的输出结果&#xff0c;常规的断言一般包…...

flutter实现上拉到底部加载更多数据

实现上拉加载数据&#xff0c;效果如下&#xff1a; flutter滚动列表加载数据 使用的库主要是infinite_scroll_pagination , 安装请查看官网 接口用的是https://reqres.in/提供的接口 请求接口用到的库是dio 下面主要是介绍如何使用infinite_scroll_pagination实现上拉加载…...

UE4 Niagara Module Script 初次使用笔记

这里可以创建一个Niagara模块脚本 创建出来长这样 点击号&#xff0c;输出staticmesh&#xff0c;点击它 这样就可以拿到对应的一些模型信息 这里的RandomnTriCoord是模型的坐标信息 根据坐标信息拿到位置信息 最后的Position也是通过Map Set的号&#xff0c;选择Particles的P…...

【Spring Boot 源码学习】JedisConnectionConfiguration 详解

Spring Boot 源码学习系列 JedisConnectionConfiguration 详解 引言往期内容主要内容1. RedisConnectionFactory1.1 单机连接1.2 集群连接1.3 哨兵连接 2. JedisConnectionConfiguration2.1 RedisConnectionConfiguration2.2 导入自动配置2.3 相关注解介绍2.4 redisConnectionF…...

联想服务器-HTTP boot安装Linux系统

HTTP boot与传统PXE的主要差异 HTTP不再需要使用UDP协议的tftp服务&#xff08;连接不可靠、不支持大文件&#xff09;了&#xff0c;只需要dhcp 和http 两个服务即可&#xff0c;支持较稳定的大文件传输。 实验环境 ThinkSystem服务器SR650V2 SR660V2 通过HTTP boot安装Cen…...

容器滚动更新过程中流量无损

应用在发布或重启的期间会出现少量的 5xx 异常&#xff0c;应该如何解决&#xff1f; 我们发现导致流量有损的原因有很多&#xff0c;比如&#xff1a; 上线时&#xff0c;应用在就绪前收到流量&#xff0c;导致请求无法被处理&#xff1b; 下线时&#xff0c;应用没有做优雅…...

深入理解JS中的this

1、浅谈this 1.1、调用位置 在学习this的绑定过程之前&#xff0c;首先要理解调用位置&#xff0c;即函数在代码中被调用的位置&#xff0c;因此我们需要分析调用栈&#xff0c;看以下代码 function baz(){// 当前调用栈是baz// 因此调用位置就是全局作用域console。log(&qu…...

rust 基础数据类型

默认类型 大部分情况下&#xff0c;rust 可以基于上下文自动推导出变量的类型。下面代码中&#xff0c;变量 x 没有显式&#xff0c;rust 默认是 i32 类型。 fn main() {let x 5; }但也有一些例外情况&#xff0c;比如&#xff0c;字符串类型的转换中变量 x 的类型&#xff…...

ELK极简上手

目录 引言 首先&#xff0c;下载相关的包 其次&#xff0c;安装启动elasticsearch 下一步&#xff0c;安装并启动logstash 最后&#xff0c;安装并启动kibana 进一步的&#xff0c;测试数据的流动 引言 最近整理电脑发现之前的一篇ELK极简入门笔记&#xff0c;现整理发出…...

在 JavaScript 中,变量的作用域是如何确定的?

在 JavaScript 中&#xff0c;变量的作用域是由作用域链&#xff08;Scope Chain&#xff09;来确定的。作用域链是指变量在执行期间访问的作用域的链式结构。 JavaScript 中的作用域分为全局作用域和局部作用域&#xff08;函数作用域和块级作用域&#xff09;。 全局作用域…...

常见面试题-TCP三次握手四次挥手

TCP 三次握手/四次挥手 参数用途SYN用于启动和建立连接时&#xff0c;同步设备之间的序列号。0到2^32 - 1的随机数。ACK向另一端确认已经收到 SYN&#xff0c;数值为收到 SYN 增一。SYN-ACK确认之前收到了 SYN&#xff0c;数值为自定义值。FIN终止连接。RST重置连接。 三次握…...

前端框架Vue学习 ——(六)Vue组件库Element

文章目录 Element 介绍快速入门常见组件表格分页Dialog 对话框组件表单 Container 布局容器 Element 介绍 Element&#xff1a;是饿了么团队研发的&#xff0c;一套为开发者、 设计师和产品经理准备的基于Vue 2.0的桌面端组件库。 组件&#xff1a;组成网页的部件&#xff0c;…...

第六章:Property-based Testing and Test Oracles

文章目录 Test OraclesActive and Passive Test OraclesTypes of Test OraclesFormal, executable specificationsSolved examplesMetamorphic oraclesAlternative implementations (备用实现)Heuristic oracles (启发式)The Golden Program!Oracle Deviation (Oracle偏差)T…...

react生命周期函数

React 组件的生命周期可分为三大阶段&#xff1a;挂载阶段&#xff08;Mounting&#xff09;、更新阶段&#xff08;Updating&#xff09;和卸载阶段&#xff08;Unmounting&#xff09;。 1.挂载阶段&#xff08;Mounting&#xff09; 在组件被插入到 DOM 中后&#xff0c;会…...

QSqlDatabase使用Sqlite

QSqlDatabase使用Sqlite Sqlite本身就可以被内嵌在程序中&#xff0c;QSqlDatabase也自带Sqlite驱动&#xff0c;无需任何第三方依赖&#xff0c;可以直接使用 QSqlDatabase _db QSqlDatabase::addDatabase("QSQLITE"); QString dbPath "/path/to/xxx.db&qu…...

宝马——使用人工智能制造和驾驶汽车

德国汽车制造商宝马(BMW)每年在全球制造和销售250万台汽车&#xff0c;其品牌包括宝马、MINI和劳斯莱斯。 宝马汽车以其卓越的性能和对新技术的应用而著名&#xff0c;它是道路上最精致的汽车之一&#xff0c;并且和其竞争对手戴姆勒(Daimler)一样&#xff0c;在将自动驾驶汽车…...

java入门,Map<? extends String, ?>

一、前言 是不是平时写业务代码的时候很少用到这个写法&#xff1a;Map<? extends String, ?>&#xff0c;这是Map类型&#xff0c;Map的键是? extends String 类型&#xff0c;值是?。为什么不是我们平时写的Map< String, Object>&#xff0c;这种写法有什么好…...

Spring Boot 统一处理功能

目录 1.用户登陆权限验证 1.1 每个方法验证 1.2 Spring AOP 用户统一登陆验证 1.3 拦截器 1.3.1 自定义拦截器 1.3.2 将自定义拦截器配置到系统设置中&#xff0c;并且设置拦截规则 1.3.3 排除所有的静态资源 1.4 登录拦截器&#xff08;练习&#xff09; 1.5 拦截器原…...

香港金融科技周VERTU CSO Sophie谈Web3.0的下一个风口 手机虚拟货币移动支付

10月31日&#xff0c;香港金融科技周正式拉开帷幕。这项香港金融科技界地年度盛事今年已经踏入了第八届&#xff0c;本届活动吸引超过数百位金融科技专业人士、创业者和行业领袖现场参与&#xff0c;线上参与观众超过10万人次。 在金融科技周的圆桌会议上&#xff0c;VERTU首席…...

分布式单元化

一 分布式单元化 1.1 两地三中心 顾名思义&#xff0c;两地指的是两个城市&#xff1a;同城&#xff0c;异地。三中心指的是三个数据中心&#xff1a;生产中心、同城容灾中心、异地容灾中心。 在同一个城市或者临近的城市建设两个相同的系统&#xff0c;双中心具备相当的业…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...