irpas技术客

〖Python APP 自动化测试实战篇⑥〗- 实战 - appium 定位手机元素之常用的元素定位方法_不渴望力量的哈士奇_python定位手机元素

大大的周 7867

万叶集🎉 隐约雷鸣,阴霾天空。 🎉🎉 但盼风雨来,能留你在此。 🎉


前言: ? 作者简介:渴望力量的哈士奇 ?,大家可以叫我 🐶哈士奇🐶 ,一位致力于 TFS - 全栈 赋能的博主 ? 🏆 CSDN博客专家认证、新星计划第三季全栈赛道 top_1 、华为云享专家、阿里云专家博主 🏆 📫 如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀 💬 人生格言:优于别人,并不高贵,真正的高贵应该是优于过去的自己。💬 🔥 如果感觉博主的文章还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主哦


专栏系列(点击解锁)学习路线指引知识定位 🔥Python全栈白皮书🔥 零基础入门篇 以浅显易懂的方式轻松入门,让你彻底爱上Python的魅力。 语法进阶篇 主要围绕多线程编程、正则表达式学习、含贴近实战的项目练习 。 自动化办公篇 实现日常办公软件的自动化操作,节省时间、提高办公效率。 自动化测试实战篇 从实战的角度出发,先人一步,快速转型测试开发工程师。 数据库开发实战篇 更新中 爬虫入门与实战 更新中 数据分析篇 更新中 前端入门+flask 全栈篇 更新中 django+vue全栈篇 更新中 拓展-人工智能入门 更新中 网络安全之路 踩坑篇 记录学习及演练过程中遇到的坑,便于后来居上者 网安知识扫盲篇 三天打鱼,不深入了解原理,只会让你成为脚本小子。 vulhub靶场漏洞复现 让漏洞复现变得简单,让安全研究者更加专注于漏洞原理本身。 shell编程篇 不涉及linux基础,最终案例会偏向于安全加固方向。 [待完结] WEB漏洞攻防篇 2021年9月3日停止更新,转战先知社区等安全社区及小密圈 渗透工具使用集锦 2021年9月3日停止更新,转战先知社区等安全社区及小密圈 点点点工程师 测试神器 - Charles 软件测试数据包抓包分析神器 测试神器 - Fiddler 一文学会 fiddle ,学不会倒立吃翔,稀得! 测试神器 - Jmeter 不仅是性能测试神器,更可用于搭建轻量级接口自动化测试框架。 RobotFrameWork Python实现的自动化测试利器,该篇章仅介绍UI自动化部分。 Java实现UI自动化 文档写于2016年,Java实现的UI自动化,仍有借鉴意义。 MonkeyRunner 该工具目前的应用场景已不多,文档已删,为了排版好看才留着。


文章目录 🐳 常用的元素定位方法🐬 id 定位🐬 classname 定位🐬 Xpath 定位 🐳 层级定位

对象的定位是在我们自动化测试领域非常非常关键的一步,也可以说是最关键的一步。毕竟对象都没有定位到,根本就没法操作啊。所以在这一章节中,希望大家能够多多动手去操作,不要仅仅是看。毕竟 “手是好汉,眼是懒蛋” 不是。

今天的章节主要还是为大家介绍常用的 元素定位方法 与 层级定位方法。

🐳 常用的元素定位方法

接下来我们先看看一些比较常用的元素定位方式,比如 id、clasname、xpath 等定位方式; 还有在 web 自动化中经常用到的层级定位 ,这个方法再 app 自动化领域同样的适用;最后还会为大家介绍一种超级定位方式 —> uiautomator text 定位,这种超级定位方式将会放在下一章节为大家介绍。

🐬 id 定位

区别于 web 自动化的利用开发者工具查看web页面元素的定位方式,在 app 自动化中我们所使用的是 appium 本身自带的功能来针对元素进行定位。当 appium inspector 启动之后,就可以通过 Select Element 来选中想要定位的元素,同时也就可以获取该元素的一些相关属性值。

见下图:



无论是在 app 自动化 还是 web 领域的自动化, id 属性都是唯一的。appium 在之前的版本中还支持 name 定位,但是从去年开始,最新版的 appium 中就永久性的去掉了 name 定位方法,取而代之的是 id 定位。

所以如果小伙伴们使用的是最新版本的 appium 的话,是无法通过 name 定位方法去定位元素的,在实际的工作中,大家也是非常喜欢 id 定位这种方式。

当然了也会出现没有 id 属性的情况,那是因为开发人员没有写 id 这个属性。这个时候就需要我们与开发去沟通,或者换一个方式来进行元素的定位了。(还有一张方式就是 环境里的安卓版本比较老,所以就没有 id 这个属性,也就谈不上通过 id 来进行定位了 )

示例代码如下:(点击百度APP启动页的"同意元素")

# coding=utf-8 from time import sleep from appium import webdriver # appium 的特色就是将安卓、IOS的底层封装成了 webdriver 类型的语句 from appium.webdriver.common.appiumby import By ''' 区别于WEB自动化,APP自动化需要有一个设备的概念; 所谓的设备概念,就是启动的参数 ''' # 启动参数 desired_caps = {} # 定义 desired_caps 变量,用以赋值很多的启动信息 desired_caps['platformName'] = 'Android' # 设备名称、系统为 "Android" desired_caps['platformVersion'] = '7.1.2' # 这里是在夜神模拟器的设置中心查看安卓版本是 "7.1.2" ,后续会告诉大家如何切换版本 desired_caps['deviceName'] = '127.0.0.1:62001' # 这里如果是真机的话填写的是设备名称;因为我们用的是模拟器,填写的是IP端口号 desired_caps['appPackage'] = 'com.baidu.searchbox' # APP 的包名;这里我们使用的是通讯录 desired_caps['appActivity'] = 'com.baidu.searchbox.SplashActivity' # 启动的界面的名字(也或者叫启动名,默认是 "." 开头的) desired_caps['automationName']='UiAutomator1' # 声明手机驱动 driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps) # 注册到这个节点上,传入 "desired_caps"。这个节点就是 "appium" 开启的端口节点 # 定位到要操作的元素,即点击那个 "同意" 按钮 sleep(1) driver.find_element(by=By.ID, value='com.baidu.searchbox:id/obfuscated').click() sleep(3) driver.quit()

运行结果如下:



🐬 classname 定位

接下来我们再尝试一下,是否可以通过 classname 属性进行定位,见下图:



从上面的截图来看,我们使用的 classname 的方式定位到的元素是一组,所以不适合当前场景,只能考虑通过其他方式定位。

🐬 Xpath 定位

与WEB自动化一样,在 app 端,我们也可以使用 Xpath 来进行 app 端的元素定位,见下图:



OK,Xpath 确实可以定位到这个元素,那么就将其写入到脚本中吧。(不过得吐槽一句,这 Xpath 的值是真的很不人性化。)

# coding=utf-8 from time import sleep from appium import webdriver # appium 的特色就是将安卓、IOS的底层封装成了 webdriver 类型的语句 from appium.webdriver.common.appiumby import By ''' 区别于WEB自动化,APP自动化需要有一个设备的概念; 所谓的设备概念,就是启动的参数 ''' # 启动参数 desired_caps = {} # 定义 desired_caps 变量,用以赋值很多的启动信息 desired_caps['platformName'] = 'Android' # 设备名称、系统为 "Android" desired_caps['platformVersion'] = '7.1.2' # 这里是在夜神模拟器的设置中心查看安卓版本是 "7.1.2" ,后续会告诉大家如何切换版本 desired_caps['deviceName'] = '127.0.0.1:62001' # 这里如果是真机的话填写的是设备名称;因为我们用的是模拟器,填写的是IP端口号 desired_caps['appPackage'] = 'com.baidu.searchbox' # APP 的包名;这里我们使用的是通讯录 desired_caps['appActivity'] = 'com.baidu.searchbox.SplashActivity' # 启动的界面的名字(也或者叫启动名,默认是 "." 开头的) desired_caps['automationName']='UiAutomator1' # 声明手机驱动 driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps) # 注册到这个节点上,传入 "desired_caps"。这个节点就是 "appium" 开启的端口节点 # 定位到要操作的元素,即点击那个 "同意" 按钮 sleep(1) driver.find_element(by=By.XPATH, value='/hierarchy/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.RelativeLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.TextView[2]').click() sleep(3) driver.quit()

运行结果如下:



🐳 层级定位

OK,接下来我们就以 "百度搜索框" 为例,来演示一下搜索功能。实际上在我们点击 "百度搜索框" 的时候会发现一个问题,那就是,初始页面展示的搜索框,在我们点击之后准备输入搜索内容的情况下,会出现两个不同的页面,见下图:



所以这里我们就需要两次的元素定位,最后再针对搜索框,利用层级定位的方式,输入我们想要搜索的内容。以第二个页面中的搜索框为例,就可以利用层级定位的方式来实现(不过这里我觉得略微有些鸡肋…)



代码示例如下:

# coding=utf-8 from time import sleep from appium import webdriver # appium 的特色就是将安卓、IOS的底层封装成了 webdriver 类型的语句 from appium.webdriver.common.appiumby import By # 启动参数 desired_caps = {} # 定义 desired_caps 变量,用以赋值很多的启动信息 desired_caps['platformName'] = 'Android' # 设备名称、系统为 "Android" desired_caps['platformVersion'] = '7.1.2' # 这里是在夜神模拟器的设置中心查看安卓版本是 "7.1.2" ,后续会告诉大家如何切换版本 desired_caps['deviceName'] = '127.0.0.1:62001' # 这里如果是真机的话填写的是设备名称;因为我们用的是模拟器,填写的是IP端口号 desired_caps['appPackage'] = 'com.baidu.searchbox' # APP 的包名;这里我们使用的是通讯录 desired_caps['appActivity'] = 'com.baidu.searchbox.SplashActivity' # 启动的界面的名字(也或者叫启动名,默认是 "." 开头的) desired_caps['automationName']='UiAutomator1' # 声明手机驱动 driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps) # 注册到这个节点上,传入 "desired_caps"。这个节点就是 "appium" 开启的端口节点 # 定位到要操作的元素 sleep(1) # driver.find_element(by=By.ID, value='com.baidu.searchbox:id/obfuscated').click() driver.find_element(by=By.XPATH, value='/hierarchy/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.RelativeLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.TextView[2]').click() sleep(3) # 点击首页的搜索框 driver.find_element(by=By.XPATH, value='//android.widget.LinearLayout[@content-desc="百度搜索,请输入"]/android.widget.FrameLayout[2]').click() sleep(1) # 通过层级定位,定位搜索输入框 driver.find_element(by=By.XPATH, value='//android.widget.RelativeLayout[@content-desc="请输入搜索关键词"]').find_element(by=By.XPATH, value='//android.widget.RelativeLayout[@content-desc="请输入搜索关键词"]/android.widget.EditText').send_keys('Appium') sleep(1) # 点击 "搜索" 按钮 driver.find_element(by=By.XPATH, value='/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/com.baidu.searchbox.widget.SlidingPaneLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.RelativeLayout/android.widget.RelativeLayout/android.widget.TextView').click() sleep(2) driver.quit()

运行结果如下:



OK,这里我们发现通过这种层级定位的方式也是没问题的。所以不仅仅是 web 自动化支持这样的层级定位, app 自动化同样支持类似的层级定位。

以上这些是比较常用的基础定位,可以解决我们日产工作中 90%的元素定位问题 (利用 id、classname、xpath 的方式解决定位问题)。但是呢我们还有一种终极的定位方式,那就是安卓的 uiautomator 定位方式,前文也介绍过, appium 的底层其实就是基于 uiautomator 的封装、大量的引用了 uiautomator 的底层。所以完全可以使用 uiautomator 的方式来进行官方的、便捷的元素定位,这部分知识点,将会在下一章节进行详细的讲解。




1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #python定位手机元素 #毕竟 #不是