通过Appium和Xcode Accessibility Inspector获取iOS应用元素定位的方法

在 iOS 移动应用程序上使用选择器查找元素定位是我们在移动端 UI 自动化测试的先决条件。
但是,由于应用程序内容在原生 iOS 应用程序中的呈现方式,我们可以用来定位应用程序元素的选择器与 Web 浏览器元素有很大不同。
在本文中,我们将了解 3 种常用方法来确定元素选择器,以便在 iOS 应用程序中查找元素定位,进而用于进行自动化移动 UI 测试。

XCTest 框架和 Appium XCUITest 驱动程序
对于原生 iOS 应用,应用内容通过 WKWebView(iOS 8.0 或更高版本)呈现。Apple 开发的官方 XCTest 框架提供了一种方法,可以根据每个元素的渲染内容,根据其元素类型和 WKWebView 上下文中的元素属性来定位元素。但是,XCTest 框架仅支持 Swift 和 Objective-C,因此当 iOS 应用程序是用 React Native 而不是 Swift 编写时,它就不适用于移动端 UI 自动化测试了。 
如果已经对于移动端 UI 自动化测试有所了解或应用的话,可能会对这样一种替代方案有所耳闻: Appium XCUITest Driver(以前称为 UIAutomation Driver for iOS)。 Appium XCUITest 驱动程序利用 Apple 的 XCTest 框架及其底层库来提升 iOS 应用程序的自动化,并支持多种语言,包括 Java、Python、javascript、Ruby、C# 和 PHP。接下来将以 Appium XCUITest 驱动程序为例来看看我们如何检查 iOS 应用程序并找到元素定位的。

查找 iOS 移动应用的元素选择器
XCTest 框架或 Appium XCUITest 驱动程序提供了一种通过编程方式与 app 元素交互的方法,但我们仍然需要手动识别元素选择器并将选择器提供给我们的元素进行 UI 自动化测试。由于我们必须使用 iOS 模拟器或真实的 iOS 设备来打开应用程序,而设备上并没有内置的检查器来为我们提供这些信息,反观在各种浏览器中,就有各种开发者工具可以用来提供这些信息。
 
以下是 3 种经常使用来检查原生 iOS 应用程序内容并确定选择器以定位元素的方法。 
顺便说一下,我们将用于演示的示例 iOS 应用程序如下。它使用 React Native 编写并在 iOS 模拟器上运行。

(在 iOS 模拟器上运行的示例 react-native 应用程序的屏幕截图)

1. driver.getPageSource()

Appium XCUITest 驱动程序提供了一种方法: getPageSource(),它可以在终端控制台中直接打印出当前呈现的应用页面的页面源代码。这是一种可以快速查看应用页面中所有元素的全貌,并确定可用于获取元素定位的元素类型和属性的快速方法。
只需要在 UI 自动化测试中插入以下代码(如下Java代码):
System.out.println(driver.getPageSource());
下面是示例应用程序的页面源代码片段。

<XCUIElementTypeOther type="XCUIElementTypeOther" name="Welcome to Example App" label="Welcome to Example App" enabled="true" visible="true" x="0" y="76" width="375" height="77">
  <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="Welcome to Example App" name="Welcome to Example App" label="Welcome to Example App" enabled="true" visible="true" x="24" y="100" width="327" height="29"/>
</XCUIElementTypeOther>
<XCUIElementTypeOther type="XCUIElementTypeOther" name="Section One This is the description for Section One." label="Section One This is the description for Section One." enabled="true" visible="true" x="0" y="184" width="375" height="55">
  <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="Section One" name="Section One" label="Section One" enabled="true" visible="true" x="24" y="184" width="327" height="25"/>
  <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="This is the description for Section One." name="This is the description for Section One." label="This is the description for Section One." enabled="true" visible="true" x="24" y="216" width="327" height="23"/>
</XCUIElementTypeOther>
<XCUIElementTypeOther type="XCUIElementTypeOther" name="Section Two This is the description for Section Two." label="Section Two This is the description for Section Two." enabled="true" visible="true" x="0" y="270" width="375" height="54">
  <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="Section Two" name="Section Two" label="Section Two" enabled="true" visible="true" x="24" y="270" width="327" height="25"/>
  <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="This is the description for Section Two." name="This is the description for Section Two." label="This is the description for Section Two." enabled="true" visible="true" x="24" y="302" width="327" height="23"/>
</XCUIElementTypeOther>
<XCUIElementTypeOther type="XCUIElementTypeOther" name="Section Three This is the description for Section Three. Example Button" label="Section Three This is the description for Section Three. Example Button" enabled="true" visible="true" x="0" y="356" width="375" height="113">
  <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="Section Three" name="Section Three" label="Section Three" enabled="true" visible="true" x="24" y="356" width="327" height="25"/>
  <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="This is the description for Section Three." name="This is the description for Section Three." label="This is the description for Section Three." enabled="true" visible="true" x="24" y="388" width="327" height="44"/>
  <XCUIElementTypeButton type="XCUIElementTypeButton" name="Example Button" label="Example Button" enabled="true" visible="true" x="24" y="431" width="327" height="38"/>
</XCUIElementTypeOther>

可以看到,打印出来的页面源代码提供了每个元素的丰富信息,包括元素的类型和属性等,我们可以使用这些信息来确定每个元素定位。
例如,对于 Example Button  按钮元素,其页面源代码为:
<XCUIElementTypeButton type="XCUIElementTypeButton" name="Example Button" label="Example Button" enabled="true" visible="true" x="24" y="431" width="327" height="38"/> </XCUIElementTypeOther>
我们可以很容易地确定它的元素定位为:
driver.findElement(By.xpath("//XCUIElementTypeButton[@name='Example Button']"))

2. Accessibility Inspector

Accessibility Inspector是 Apple 开发的一个鲜为人知但非常有用的工具,可帮助开发人员提高 iOS 应用程序的可访问性。该工具是与 Xcode 捆绑在一起的,因此需要在 Mac 电脑上安装Xcode。Accessibility Inspector 通过解析和识别 iOS 应用程序上的每个元素并检查元素的类型和可访问性标签来明确 iOS 应用程序的可访问性功能及问题。由于它提供了有关应用程序上每个元素的详细信息,因此它也可以很容易地用于在自动化 UI 测试中识别每个元素的选择器。
下面是 Accessibility Inspector 为 Example Button 按钮元素提供的信息:

可以看到,Accessibility Inspector 显示 Example Button  按钮元素具有 Button 类型和 Example Button标签,因此我们就可以使用它们来确定该元素定位:
driver.findElement(By.xpath("//XCUIElementTypeButton[@name='Example Button']"))
在确定确切的元素选择器方面,Accessibility Inspector 一开始并不总是很容易使用,但是一旦熟悉了 Accessibility Inspector 如何呈现有关应用程序元素的信息,它将是一种快速且轻量级的工具,可以轻松完成工作。
 
实操示例:
1)Accessibility Inspector 在Xcode的入口:Xcode —— Open Developer Tool —— Accessibility Inspector


2)连接好设备后点击开始按钮即可开始使用。

3. Appium Desktop

Appium Desktop 是 Appium 团队为 Mac、Windows 和 Linux 开发的桌面应用程序。它是许多 Appium 开发人员在移动端UI自动化测试中检查 iOS 和 Android 应用程序元素的流行工具。 
下面是 Appium Desktop 显示的关于 Example Button 按钮元素的内容:

 (示例应用和 Appium 桌面的屏幕截图)

可以看到,中间部分的 App Source 显示了当前应用页面的完整层次结构,右侧部分的 Selected Element 显示了详细的信息和属性列表 。更有用的是它还提供了用于定位当前元素的最佳选择器,即 accessibility id 或者 xpath,这二者非常方便使用。
Appium Desktop 还提供了其他不错的功能,例如直接单击/点击所选元素,以及在应用页面更改后刷新页面源。可以参考官方的Appium Desktop代码仓库了解更多信息。
 
最后的话
总之,Appium Desktop 是一种用于检查 iOS 应用程序上的元素获取元素定位的流行且推荐的工具。如果你是刚开始编写 UI 自动化测试,那么利用它来全面了解应用程序和页面元素也很有用。一旦你相当熟悉了应用程序和页面结构,直接在代码中使用driver.getPageSource() 或使用 Accessibility Inspector 是快速找到元素定位的好选择。
 

Reference

1、3 Ways to Find Element Selector for iOS App with Appium:https://stephenweixu.com/blog/3-ways-to-find-element-selector-for-ios-app-with-appium
2、iOS 测试 WebDriverAgent 简介:https://testerhome.com/topics/4904 (WebDriverAgent Inspector 的使用)
3、Appium1.6 定位iOS元素和操作元素 :https://www.cnblogs.com/meitian/p/7373460.html
4、Appium+Python3+iOS定位元素:https://wangxiaoxi.cn/posts/appium-ios-2/ (元素定位慢的问题)
5、uiautomator2 使用Python测试 Android应用:https://www.cnblogs.com/fnng/p/8486863.html (也有提到 这种方法可以获取元素定位 )
 

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

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

相关文章

百元开放式耳机怎么选?五款入手不亏的上乘产品推荐

耳机已经成为了我们生活中不可或缺的一部分&#xff0c;无论是通勤路上的音乐陪伴&#xff0c;还是家中观影的沉浸体验&#xff0c;一款优质的耳机都能为我们带来极大的享受。而在众多耳机类型中&#xff0c;开放式耳机因其独特的声场表现和舒适的佩戴体验&#xff0c;受到了越…

弹性伸缩 AS

&#x1f341;博主简介&#xff1a; &#x1f3c5;云计算领域优质创作者 &#x1f3c5;2022年CSDN新星计划python赛道第一名 &#x1f3c5;2022年CSDN原力计划优质作者 &#x1f3c5;阿里云ACE认证高级工程师 &#x1f3c5;阿里云开发者社区专…

JavaScript进阶5之垃圾回收(计算机组成、解释与编译、JavaScript引擎、垃圾回收、内存管理)、运行机制(浏览器进程分类、浏览器事件循环)

垃圾回收&运行机制 垃圾回收计算机组成解释与编译JavaScript引擎V8引擎 垃圾回收引用计数法标记清除&#xff08;mark-sweep&#xff09;算法 内存管理新生代 运行机制浏览器进程分类&#xff1a;浏览器事件循环宏任务微任务整体流程浏览器事件循环案例一案例二 垃圾回收 …

成都克鲁斯机器人电路板故障维修攻略,快来了解一下!

一、克鲁斯机器人电路板维修步骤 断开电源&#xff1a;在进行电路维修前&#xff0c;务必断开机器人的电源&#xff0c;确保安全。 拆卸电路板&#xff1a;根据电路图或维修手册&#xff0c;小心拆卸故障电路板。注意记录拆卸过程中的细节&#xff0c;以便后续重新安装。 更换损…

Linux中APP读取按键的4种方法

查询方式 驱动程序中构造、注册一个file_operations结构体&#xff0c;里面有对应的open,read函数。 APP 调用 open 时&#xff0c;导致驱动中对应的 open 函数被调用&#xff0c;在里面配置 GPIO 为输入引脚。APP 调用 read 时&#xff0c;导致驱动中对应的 read 函数被调用&a…

一个金融长期主义案例:金融壹账通的财务减亏与生产力创新之路

产业变革正在进入新一轮竞速期&#xff0c;社会对新质生产力的需求越来越迫切。在此背景下&#xff0c;金融业也正在坚定重塑自我、向外赋能的决心。 在微观的企业角度上&#xff0c;改变也正悄然发生。3月18日&#xff0c;在美港股双重上市的金融壹账通公布2023年年度业绩报告…

正则表达式不会用?一篇教你快速搞懂 !

目录 前言一、基础字符二、一系列常用的字符&#xff1b;1、一些元字符&#xff08;Meta-characters&#xff09; 三、一些高级概念1、贪婪与懒惰匹配2、两个实例加深理解1.颜色值的匹配&#xff1a;RGBS值2.ipv4 地址匹配 四、正则表达式常用语法**1.Flags&#xff08;标志符或…

测试开发工程师(QA)职业到底需要干些什么?part5:性能测试工程师QA

工作职责 性能测试工程师&#xff08;Performance Testing Engineer&#xff09;是负责评估和优化软件、应用程序或系统在不同负载和压力条件下的性能的专业人员。他们的工作职责包括以下几个方面&#xff1a; 性能测试计划&#xff1a;性能测试工程师与开发团队、产品团队和系…

工作的第二天

昨天的进度 写今天思路如何做评论表的增删该查评论表的增加 选择用户和商品 弹出框出现了问题 检查代码 结构没有问题 定义变量也没有问题 控制太中也没有报错信息 问题解决了 出现的问题在哪里定义的变量都有问题应该现在 setup 上面 定义一个 变量 const ref ref(fals…

Autosar-CanNm、Nm配置详解(免费)-2

3.5NM配置项 3.5.1NmGlobalConstants NmNumberOfChannels Nm管理几个Can通信&#xff0c;通信我们只有智能进入网需要网络管理&#xff0c;因此一般这里只需要填1。 NmNumberOfClusters 如果NM需要与几个CanNm进行协同处理的话&#xff0c;那需要把这些配置为Cluster,即组…

让 AI 帮你写代码,开发提效神器来了

如今&#xff0c;大量程序员已经习惯在 AI 辅助下进行编程。据调研&#xff0c;AI 编码工具将程序员工作效率提升 50% 以上。 通义灵码是目前国内最受开发者喜爱的 AI 编码助手&#xff0c;可以提供行级/函数级实时续写、自然语言生成代码、单元测试生成、代码优化、注释生成、…

设置http响应报文

一、总结&#xff1a; (1)设置响应状态码&#xff1a; response.statusCode (2)设置响应状态描述&#xff1a; response.statusMessage() 使用的极少 (3)设置响应头信息&#xff1a; response.setHeader(头值,头名) (4)设置响应体&#xff1a; response…

一文详解CDGA证书含金量,非常详细!

在信息技术飞速发展的今天&#xff0c;数据已成为企业宝贵的资产。正确地管理和治理这些数据&#xff0c;对于企业实现数据价值最大化、保障数据安全和合规至关重要。这也使得数据治理领域的专业人才需求持续增长。CDGA&#xff08;Certified Data Governance Architect&#x…

【并发】第三篇 Hash冲突的解决方法

导航 一. 简介二. 解决Hash冲突的方法1. 开放地址法1.1 线性探测再散列1.2 二次探测再散列1.3 伪随机探测再散列2. 链地址法3. 再哈希法一. 简介 哈希(hash)是将任意长度的输入数据转化为固定长度的输出数据的算法。哈希函数会将输入数据压缩并映射为一个固定长度的哈希值,…

Trello国内替代工具有哪些?分享5款

盘点5款类似Trello的本地部署项目管理工具&#xff1a;1.PingCode&#xff1b;2.Worktile&#xff1b;3.Teambition&#xff1b;4.redmine&#xff1b;5.TAIga.io。 Trello是一款杰出的协作与工作管理应用&#xff0c;专为追踪团队项目、凸显当前活动任务、分配责任人&#xff…

面试题 之 webpack

1.说说你对webpack理解&#xff1f;解决什么问题&#xff1f; Webpack 是实现前端项目的模块化&#xff0c;用于现代 JavaScript 应用程序的静态模块打包工具&#xff0c;被webpack 直接引用的资源打包进 bunde.js的资源&#xff0c;当webpack 处理应用程序时,它会在内部构建一…

Charles for Mac 强大的网络调试工具

Charles for Mac是一款功能强大的网络调试工具&#xff0c;可以帮助开发人员和测试人员更轻松地进行网络通信测试和调试。以下是一些Charles for Mac的主要特点&#xff1a; 软件下载&#xff1a;Charles for Mac 4.6.6注册激活版 流量截获&#xff1a;Charles可以截获和分析通…

CANalyzer使用_04 使用CAN报文发送数据

本文手把手介绍使用CAN来发送数据。分为创建工程&#xff0c;创建CAN报文&#xff0c;运行效果&#xff0c;参考文献。 1 创建工程 双击“CANalyzer->单击“I accept”->等一会等软件打开后&#xff0c;单击“File”->单击"New"->双击"CAN 500kBa…

2G-3G-4G-5G 语音方案

1.2G、3G时代&#xff0c;语音业务采用CS&#xff08;Circuited Switched&#xff0c;电路交换&#xff09;技术&#xff0c;即手机在通话前需在网络中建立一条独占资源的线路&#xff0c;直到通话结束才拆除。这种古老的技术存在耗资源、组网复杂、效率低等缺点。 2. 进入4…

每日学习笔记:C++ STL迭代器特性(Iterator Trait)、自定义迭代器

迭代器特性(Iterator Trait) 注意不同的迭代器种类类型之前有继承关系&#xff1a; 为迭代器编写泛型函数 自定义迭代器 实例