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

解决 App 自动化测试的常见痛点!

App 自动化测试中有些常见痛点问题,如果框架不能很好的处理,就可能出现元素定位超时找不到的情况,自动化也就被打断终止了。很容易打消做自动化的热情,导致从入门到放弃。比如下面的两个问题:

一是 App 启动加载时间较久(可能 App 本身加载慢,可能移动设备本身加载应用速度慢,也可能首页广告时间较长)。

另一个是各种弹框的出现,广告弹框,升级弹框,评价弹框等。在框架中如果不能处理好上面的情况,

以雪球 App 出现的几种弹框举例:

弹框一:

弹框二:

弹框三:

  • 弹框的影响范围
  • 弹框对我们自动化的影响主要是用例执行的打断,而至于弹框中广告内容的跳转或评价信息填写等属于另外的测试,因此我们主要是要将弹框处理消失,使应用回到用例执行的 PO;
  • 弹框的消失方式
  • 观察弹框,我们会发现一般为了保证用户体验,弹框都会方便用户进行一键消除,例如上述中雪球的各种弹框,可能点击一个叉号,可能任意点击其他地方,或者评价框这种直接点击“下次再说”等。
  • 弹框的处理效果
  • 自动化执行的任何时候,任意的弹框都可能出现,在这个时候用例不能失败,需要将对应的弹框正确处理后继续执行原用例,原用例的执行过程不受影响。
  1. 将需要处理的弹框元素加入到一个黑名单List中,遍历List,通过findElements方法得到的List大小来判断弹框元素是否存在,存在即点击处理
public static void handleAlert(){List<By> alertBox = new ArrayList<>();alertBox.add(By.id("ib_close"));   //广告弹框alertBox.add(By.id("md_buttonDefaultNegative")); //评价弹框alertBox.forEach(alert->{By adsLocator = alert;List<WebElement> ads = driver.findElements(adsLocator);if (ads.size() >= 1) {ads.get(0).click();}});}
  1. 将handleAlert()方法加到driver.findElement方法之前,使定位前先判断弹框的存在与否并进行处理
public static WebElement findElement(By by) {System.out.println(by);handleAlert();return driver.findElement(by);}

上述方法初步解决了弹框问题,但是缺点也很明显。

缺点:每次定位元素前都需要处理弹框,影响执行效率,速度较慢 因此我们引入try catch来解决此问题

现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:691998057【暗号:csdn999】

我们利用try catch的异常捕获处理的机制,让元素仅在定位失败时才进入弹框处理handleAlert()方法,处理完毕后重新返回driver.findElement(by),对原case元素继续进行定位执行;这样就大大提升了处理效率,使处理更为精准。

public static WebElement findElement(By by) {try {System.out.println(by);return driver.findElement(by);} catch (Exception e) {System.out.println("进入弹框处理");handleAlert();return driver.findElement(by); }}

递归处理:
一般情况下我们一次只会出现一个弹框,但是例外的是可能有一个以上的弹框同时出现,这样的话虽然处理了其中一个弹框,但是剩下的弹框依然会阻断用例的正常执行,这个时候就可以使用递归的方法,在处理完弹框后返回findElement方法自身,继续进行try catch,使之进入弹框处理逻辑

public static WebElement findElement(By by) {try {System.out.println(by);return driver.findElement(by);} catch (Exception e) {System.out.println("进入弹框处理");handleAlert();return findElement(by); }}

注意:
使用递归方法后有一个问题,就是假如并不是因为某个弹框的出现而导致的定位失败,而这个时候通过try catch进入到弹框处理逻辑后,由于并未匹配到弹框元素,所以递归就会进入一个死循环,不断重复着弹框处理的逻辑,所以使用递归时我们也需要对其次数进行限制;一般两个弹框同时出现已经算多的了,所以建议可以将递归的次数限制到最多两次便退出。

static int i = 1;
public static WebElement findElement(By by) {try {System.out.println(by);return driver.findElement(by);} catch (Exception e) {if (i > 2){   //设置最多递归两次i = 1;return driver.findElement(by);}System.out.println("进入弹框处理第"+i+"次");handleAlert();i++;return findElement(by); //最后调用自身完成递归,防止多弹框同时出现造成定位失败}
}

按照上面的方法,看似已经很好的解决了弹框的处理,但是可以注意到的是:

  • 在检查弹框的时候依然使用的是appium的定位,在当前页面中根据元素的属性去一一查找定位
  • 所有的黑名单中的弹框都会被定位查找一遍

而我们实际中最想要的也是最有效率的方法应该是:

  • 只有在当前页面中存在的弹框才对其进行定位、操作、处理。为了达到我们想要的效果,就需要借助于PageSource了。

1)appium的driver提供了一个getPageSource方法,此方法可以在当前页面可以得到一个文本字符串,也可以理解为当前页面的xml,我们利用这种xml文本来进行判断,就比用appium一一定位的方式要快速和精准的多了

String pageSource = driver.getPageSource();

2)设置黑名单,黑名单要使用元素的xpath,用来和PageSource文本做匹配,判断此弹框是否存在当前页面

String adBox = "com.xueqiu.android:id/ib_close";
String gesturePromptBox = "com.xueqiu.android:id/snb_tip_text";
String evaluateBox = "com.xueqiu.android:id/md_buttonDefaultNegative";
HashMap<String,By> map = new HashMap<>();
map.put(adBox,By.id("ib_close"));
map.put(gesturePromptBox,By.id("snb_tip_text"));
map.put(evaluateBox,By.id("md_buttonDefaultNegative"));

4)遍历map,判断黑名单弹框元素是否存在于当前pageSource,存在即根据弹框处理方式进行点击或其他操作(如上述中的新功能提示弹框,点击弹框自身无法消除,需点击页面其余部分方可消除)处理

map.entrySet().forEach(entry ->{if (pageSource.contains(entry.getKey())){if (entry.getKey().equals("com.xueqiu.android:id/snb_tip_text")){System.out.println("gesturePromptBox found");Dimension size = driver.manage().window().getSize();//点击屏幕的中心位置,消除新功能提示弹框new TouchAction<>(driver).tap(PointOption.point(size.width/2,size.height/2)).perform();}else {//其余弹框直接点击消除driver.findElement(entry.getValue()).click();}}
});
//很多弹框的话,最好的是直接定位到到底哪个弹框在界面上,元素的判断使用xpathpublic static void handleAlertByPageSource(){String pageSource = driver.getPageSource();//可以得到一个文本字符串,也可以理解为当前页面的xml//黑名单String adBox = "com.xueqiu.android:id/ib_close";String gesturePromptBox = "com.xueqiu.android:id/snb_tip_text";String evaluateBox = "com.xueqiu.android:id/md_buttonDefaultNegative";//将标记和定位符存入mapHashMap<String,By> map = new HashMap<>();map.put(adBox,By.id("ib_close"));map.put(gesturePromptBox,By.id("snb_tip_text"));map.put(evaluateBox,By.id("md_buttonDefaultNegative"));//临时修改隐式等待时间,防止查找黑名单中元素过久driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);//遍历map,判断黑名单弹框元素是否存在于当前pageSource,存在即点击处理map.entrySet().forEach(entry ->{if (pageSource.contains(entry.getKey())){if (entry.getKey().equals("com.xueqiu.android:id/snb_tip_text")){System.out.println("gesturePromptBox found");Dimension size = driver.manage().window().getSize();new TouchAction<>(driver).tap(PointOption.point(size.width/2,size.height/2)).perform();}else {driver.findElement(entry.getValue()).click();}}});//判断完成后将隐式等待时间恢复driver.manage().timeouts().implicitlyWait(8,TimeUnit.SECONDS);}

6)最后将findElement方法中的handleAlert方法替换为handleAlertByPageSource方法即可

static int i = 1;
public static WebElement findElement(By by) {try {System.out.println(by);return driver.findElement(by);} catch (Exception e) {if (i > 2){   //设置最多递归两次i = 1;return driver.findElement(by);}System.out.println("进入弹框处理第"+i+"次");handleAlertByPageSource();i++;return findElement(by); //最后调用自身完成递归,防止多弹框同时出现造成定位失败}
}

再来解决首页加载时可能出现的坑。

App 启动加载时间较久(可能 App 本身加载慢,也可能是移动设备本身加载应用速度慢,也可能首页广告时间较长),导致定位超时,用例失败。对此我们又如下两步解决办法。

如标题所述,对首页进入使用显示等待,利用搜索控件的出现来判断是否进入了首页,这样不影响其他元素隐式等待的时间,也解决了首页初始化加载时间过长的问题。

例如雪球仅在进入首页后会出现 id为user_profile_container的用户信息控件,那么我们就可以以此为依据来判断应用是否加载完成进入了首页。

在启动方法中加入显示等待上述首页控件 30 秒,到控件可被定位时确认进入首页。

new WebDriverWait(driver,30).until(ExpectedConditions.visibilityOfElementLocated(By.id("user_profile_container")));

缺点:
但是这样有个情况不能解决:若加载完成后有弹框出现,可能就一直无法定位到首页元素,但是实际上已经加载完成,比如下图的首页广告弹框 。

文章第二部分介绍了利用 PageSource 来判断弹框是否存在的方法,在这里依然适用,还是熟悉的味道,还是同样的套路,将弹框元素 xpath 也加入 PageSource 判断,这样无论首页控件和首页弹框哪一个被发现,就都可以判断应用已经加载完成,成功进入首页,剩下的就可以交给用例和其他处理逻辑了

new WebDriverWait(driver,30).until(x ->{String xml = driver.getPageSource();Boolean checkResult = xml.contains("user_profile_container") || xml.contains("com.xueqiu.android:id/ib_close");System.out.println("主页元素查找的结果是:" + checkResult);return checkResult;});

好了,经过上面的分析之后,我们终于搞定了入门 APP 自动化测试时的老大难问题。搞定了弹框及首页启动时加载完成如何判断处理。

下面是配套资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!

最后: 可以在公众号:自动化测试老司机! 免费领取一份216页软件测试工程师面试宝典文档资料。以及相对应的视频学习教程免费分享!,其中包括了有基础知识、Linux必备、Shell、互联网程序原理、Mysql数据库、抓包工具专题、接口测试工具、测试进阶-Python编程、Web自动化测试、APP自动化测试、接口自动化测试、测试高级持续集成、测试架构开发测试框架、性能测试、安全测试等。

如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏” 一键三连哦!

相关文章:

解决 App 自动化测试的常见痛点!

App 自动化测试中有些常见痛点问题&#xff0c;如果框架不能很好的处理&#xff0c;就可能出现元素定位超时找不到的情况&#xff0c;自动化也就被打断终止了。很容易打消做自动化的热情&#xff0c;导致从入门到放弃。比如下面的两个问题&#xff1a; 一是 App 启动加载时间较…...

2016NOIP普及组真题 1. 买铅笔

线上OJ&#xff1a; 一本通&#xff1a;http://ybt.ssoier.cn:8088/problem_show.php?pid1973 核心思想&#xff1a; 向上取整的代码 (m (n-1))/n 。&#xff08;本题考点与2023年J组的第一和第二题一样&#xff09; 比如需要买31支笔&#xff0c;每包30支&#xff0c;则需要…...

机器学习—数据集(二)

1可用数据集 公司内部 eg:百度 数据接口 花钱 数据集 学习阶段可用的数据集&#xff1a; sklearn:数据量小&#xff0c;方便学习kaggle&#xff1a;80万科学数据&#xff0c;真实数据&#xff0c;数据量大UCI&#xff1a;收录了360个数据集&#xff0c;覆盖科学、生活、经济等…...

华为S5735S核心交换配置实例

以下脚本实现创建vlan2,3&#xff0c;IP划分&#xff0c;DHCP启用&#xff0c;接口划分&#xff0c;ssh,telnet,http,远程登录启用 默认用户创建admin/admin123提示首次登录需要更改用户密码S5735产品手册更多功能配置&#xff0c;移步官网参考手册配置 system-viewsysname t…...

Mysql主从复制安装配置

mysql主从复制安装配置 1、基础设置准备 #操作系统&#xff1a; centos6.5 #mysql版本&#xff1a; 5.7 #两台虚拟机&#xff1a; node1:192.168.85.111&#xff08;主&#xff09; node2:192.168.85.112&#xff08;从&#xff09;2、安装mysql数据库 #详细安装和卸载的步骤…...

【刷题】图论——最小生成树:Prim、Kruskal【模板】

假设有n个点m条边。 Prim适用于邻接矩阵存的稠密图&#xff0c;时间复杂度是 O ( n 2 ) O(n^2) O(n2)&#xff0c;可用堆优化成 O ( n l o g n ) O(nlogn) O(nlogn)。 Kruskal适用于稀疏图&#xff0c;n个点m条边&#xff0c;时间复杂度是 m l o g ( m ) mlog(m) mlog(m)。 Pr…...

使用uniapp实现小程序获取wifi并连接

Wi-Fi功能模块 App平台由 uni ext api 实现&#xff0c;需下载插件&#xff1a;uni-WiFi 链接&#xff1a;https://ext.dcloud.net.cn/plugin?id10337 uni ext api 需 HBuilderX 3.6.8 iOS平台获取Wi-Fi信息需要开启“Access WiFi information”能力登录苹果开发者网站&…...

回忆杀之手搓当年搓过的Transformer

整体代码 import mathimport paddle import paddle.nn as nn import paddle.nn.functional as Fclass MaskMultiHeadAttention(nn.Layer):def __init__(self, hidden_size, num_heads):super(MaskMultiHeadAttention, self).__init__()assert hidden_size % num_heads 0, &qu…...

【AR】使用深度API实现虚实遮挡

遮挡效果 本段描述摘自 https://developers.google.cn/ar/develop/depth 遮挡是深度API的应用之一。 遮挡&#xff08;即准确渲染虚拟物体在现实物体后面&#xff09;对于沉浸式 AR 体验至关重要。 参考下图&#xff0c;假设场景中有一个Andy&#xff0c;用户可能需要放置在包含…...

python-pytorch实现skip-gram 0.5.001

python-pytorch实现skip-gram 0.5.000 数据加载、切词准备训练数据准备模型和参数训练保存模型加载模型简单预测获取词向量画一个词向量的分布图使用词向量计算相似度参考数据加载、切词 按照链接https://blog.csdn.net/m0_60688978/article/details/137538274操作后,可以获得…...

C语言:约瑟夫环问题详解

前言 哈喽&#xff0c;宝子们&#xff01;本期为大家带来一道C语言循环链表的经典算法题&#xff08;约瑟夫环&#xff09;。 目录 1.什么是约瑟夫环2.解决方案思路3.创建链表头结点4.创建循环链表5.删除链表6.完整代码实现 1.什么是约瑟夫环 据说著名历史学家Josephus有过以下…...

【刷题篇】回溯算法(二)

文章目录 1、求根节点到叶节点数字之和2、二叉树剪枝3、验证二叉搜索树4、二叉搜索树中第K小的元素5、二叉树的所有路径 1、求根节点到叶节点数字之和 给你一个二叉树的根节点 root &#xff0c;树中每个节点都存放有一个 0 到 9 之间的数字。 每条从根节点到叶节点的路径都代表…...

Windows系统本地部署Jupyter Notebook并实现公网访问编辑笔记

文章目录 1.前言2.Jupyter Notebook的安装2.1 Jupyter Notebook下载安装2.2 Jupyter Notebook的配置2.3 Cpolar下载安装 3.Cpolar端口设置3.1 Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1.前言 在数据分析工作中&#xff0c;使用最多的无疑就是各种函数、图表、…...

自动化运维(二十七)Ansible 实战Shell 插件和模块工具

Ansible 支持多种类型的插件&#xff0c;这些插件可以帮助你扩展和定制 Ansible 的功能。每种插件类型都有其特定的用途和应用场景。今天我们一起学习Shell 插件和模块工具。 一、 Shell 插件 Ansible shell 插件决定了 Ansible 如何在远程系统上执行命令。这些插件非常关键&a…...

Jenkins使用-绑定域控与用户授权

一、Jenkins安装完成后&#xff0c;企业中使用&#xff0c;首先需要绑定域控以方便管理。 操作方法&#xff1a; 1、备份配置文件&#xff0c;防止域控绑定错误或授权策略选择不对&#xff0c;造成没办法登录&#xff0c;或登录后没有权限操作。 [roottest jenkins]# mkdir ba…...

【前端】es-drager 图片同比缩放 缩放比 只修改宽 只修改高

【前端】es-drager 图片同比缩放 缩放比 ES Drager 拖拽组件 (vangleer.github.io) 核心代码 //初始宽 let width ref(108)//初始高 let height ref(72)//以下两个变量 用来区分是单独的修改宽 还是高 或者是同比 //缩放开始时的宽 let oldWidth 0 //缩放开始时的高 let o…...

蓝桥杯第十四届蓝桥杯大赛软件赛省赛C/C++ 大学 A 组题解

1.幸运数 题目链接&#xff1a;0幸运数 - 蓝桥云课 (lanqiao.cn) #include<bits/stdc.h> using namespace std; bool deng(string& num){int n num.size();int qian 0,hou 0;for(int i0;i<n/2;i) qian (num[i]-0);for(int in/2;i<n;i) hou (num[i]-0);r…...

eclipse .project

.project <?xml version"1.0" encoding"UTF-8"?> <projectDescription> <name>scrm-web</name> <comment></comment> <projects> </projects> <buildSpec> <buil…...

react的闭包陷阱

React 的闭包陷阱是指在使用 React Hooks 时&#xff0c;由于闭包特性导致在某些函数或异步操作中无法正确访问到更新后状态或 prop 的值&#xff0c;而仍旧使用了旧值。下面通过几个代码示例来具体说明闭包陷阱的几种常见情形&#xff1a; 示例 1: useState 闭包陷阱 import…...

神经网络解决回归问题(更新ing)

神经网络应用于回归问题 优势是什么&#xff1f;&#xff1f;&#xff1f;生成数据集&#xff1a;通用神经网络拟合函数调整不同参数对比结果初始代码结果调整神经网络结构调整激活函数调整迭代次数增加早停法变量归一化处理正则化系数调整学习率调整 总结ingfnn.py进行计算&am…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...

基于IDIG-GAN的小样本电机轴承故障诊断

目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) ​梯度归一化(Gradient Normalization)​​ (2) ​判别器梯度间隙正则化(Discriminator Gradient Gap Regularization)​​ (3) ​自注意力机制(Self-Attention)​​ 3. 完整损失函数 二…...