App UI自动化--Appium学习--第二篇
如果第一篇在运行代码的时候出现问题,建议参考我的上一篇文章解决。
1、APP界面信息获取
adb logcat|grep -i displayed
代码含义是获取当前应用的包名和界面名。
根据日志信息修改代码当中的包名和界面名,就可以跳转对应的界面。
2、界面元素获取
所需工具
下载链接
下载地址
安装步骤
安装教学地址
基本配置及入门操作指南
参考操作指南
3、APPium+Python的常规操作
Appium 是一个开源工具,用于自动化测试移动应用程序(iOS 和 Android)。结合 Python 使用时,它可以帮助你编写脚本以自动执行各种操作。下面是一些基本的元素获取方式和常规操作介绍。
元素获取方式
-
通过ID查找元素
如果你知道某个元素的资源ID,可以使用find_element_by_id
方法来定位它。element = driver.find_element_by_id("resource_id")
-
通过类名查找元素
当你想通过元素的类名来定位它时,可以使用find_elements_by_class_name
方法。elements = driver.find_elements_by_class_name("android.widget.EditText")
-
通过XPath查找元素
XPath 是一种强大的路径语言,用于在 XML 文档中查找信息。同样适用于 HTML 和 XML 格式的 UI 层级结构。element = driver.find_element_by_xpath("//android.widget.TextView[@text='登录']")
-
通过Accessibility ID查找元素
Accessibility ID 提供了一种独立于平台的方式标识元素,对于跨平台测试非常有用。element = driver.find_element_by_accessibility_id("accessibility_id")
-
swipe滑动
按手机界面绝对坐标滑动,对于不同手机而言,绝对坐标会发生变化,需要使用相对坐标(获取元素坐标,根据这个元素的坐标来滑动)。
driver.swipe(start_x,start_y,end_x,end_y,duration=None)
- scroll滑动
从一个元素滑动到另一个元素,直到页面自动停止,惯性很大。
driver.scroll(origin_el, destination_el) # 参数一,滑动开始的元素,参数二滑动结束的元素。
- drag_and_drop拖拽
从一个元素滑动到另一个元素,第二个元素替代第一个元素原本屏幕上的那个位置,没有惯性。
driver.drag_and_drop(origin_el,destination _el)
常用手势操作
1. 滑动(Swipe)
滑动操作可以用来滚动页面或列表。你可以指定起始点和结束点来执行滑动动作。
# 使用 TouchAction 实现滑动
from appium.webdriver.common.touch_action import TouchActionaction = TouchAction(driver)
action.press(x=100, y=200).move_to(x=100, y=500).release().perform()
2. 长按(Long Press)
长按某个元素或屏幕上的某一点,可以模拟用户的长按操作。
# 长按一个元素
element = driver.find_element_by_id("some_element_id")
action = TouchAction(driver)
action.long_press(el=element, duration=3000).release().perform()
3. 轻敲(Tap)
轻敲是模拟用户点击屏幕的行为,可以通过坐标或直接对元素进行轻敲。
# 对元素进行轻敲
element = driver.find_element_by_id("some_element_id")
action = TouchAction(driver)
action.tap(element=element).perform()# 通过坐标进行轻敲
action = TouchAction(driver)
action.tap(x=100, y=200).perform()
4. 缩放(Pinch and Zoom)
缩放操作涉及到两个手指的动作,通常用于放大或缩小图片或地图等内容。
- 放大(Pinch Open)
driver.execute_script('mobile: pinchOpen', {'scale': 2.0, 'velocity': -1})
- 缩小(Pinch Close)
driver.execute_script('mobile: pinchClose', {'scale': 0.5, 'velocity': 1})
请注意,这些命令可能需要特定的设置或设备支持,并且不同版本的 Appium 可能会有不同的实现方式。
5. 拖拽(Drag and Drop)
拖拽是指将一个元素从一个位置拖到另一个位置。
element1 = driver.find_element_by_id("source_element_id")
element2 = driver.find_element_by_id("destination_element_id")
action = TouchAction(driver)
action.long_press(el=element1).move_to(el=element2).release().perform()
常规操作
-
点击元素
element.click()
-
输入文本
element.send_keys("Hello World!")
-
清除文本
element.clear()
-
获取元素文本
text = element.text
-
等待元素出现
在进行元素交互之前,有时需要等待元素加载完成。可以使用显式等待:from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import Bywait = WebDriverWait(driver, 10) element = wait.until(EC.presence_of_element_located((By.ID, "resource_id")))
获取手机网络状态并进行设置
在使用 Appium 进行移动应用自动化测试时,获取和设置设备的网络连接状态是一个常见的需求。Appium 提供了相应的 API 来实现这些操作。以下是如何使用 Python 和 Appium 来获取和设置手机网络连接的具体方法。
获取手机网络连接状态
你可以使用 network_connection
方法来获取当前设备的网络连接状态。不过需要注意的是,这个功能主要适用于 Android 设备,并且需要确保设备支持相应的功能。
# 获取网络连接状态
connection_status = driver.network_connection
print(f"Current network connection status: {connection_status}")
返回的状态值是一个整数,它表示当前启用的网络类型组合。例如:
0
: No network (飞行模式)1
: Airplane Mode (飞行模式)2
: Wifi enabled4
: Data enabled6
: Wifi and Data enabled
设置手机网络连接状态
要设置设备的网络连接状态,可以使用 set_network_connection
方法。你需要传递一个表示所需网络类型的整数值或通过位运算组合多个网络类型。
from appium.webdriver.connectiontype import ConnectionType# 设置为仅开启Wi-Fi
driver.set_network_connection(ConnectionType.WIFI_ONLY)# 设置为仅开启数据连接
driver.set_network_connection(ConnectionType.DATA_ONLY)# 同时开启Wi-Fi和数据连接
driver.set_network_connection(ConnectionType.ALL_NETWORK_ON)# 开启飞行模式(关闭所有网络)
driver.set_network_connection(ConnectionType.AIRPLANE_MODE)
示例代码
下面是一个完整的示例,展示了如何获取并设置设备的网络连接状态:
from appium import webdriver
from appium.webdriver.connectiontype import ConnectionType# 配置Desired Capabilities
desired_caps = {'platformName': 'Android','deviceName': 'your_device_name','appPackage': 'your_app_package','appActivity': 'your_app_activity'
}# 初始化WebDriver
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)try:# 获取当前网络连接状态current_connection = driver.network_connectionprint(f"Initial network connection status: {current_connection}")# 设置网络连接状态为仅Wi-Fidriver.set_network_connection(ConnectionType.WIFI_ONLY)print("Set network to WIFI_ONLY")# 重新获取网络连接状态以确认更改updated_connection = driver.network_connectionprint(f"Updated network connection status: {updated_connection}")finally:# 结束会话driver.quit()
注意事项
- 权限:确保你的应用或者测试脚本有足够的权限来更改网络设置。
- 平台限制:上述方法主要用于 Android 平台。对于 iOS 平台,由于系统限制,直接修改网络设置的功能可能不被支持。
- Appium 版本:确保你使用的 Appium 版本支持这些功能,某些旧版本可能不完全支持所有的网络设置选项。
在使用 Appium 进行移动应用自动化测试时,press_keycode
方法可以用来模拟物理按键的按下操作。这对于需要与设备硬件交互的场景非常有用,比如按下音量键、返回键等。
按键操作
使用 press_keycode
press_keycode
方法允许你通过指定 Android 的键码来模拟按键操作。每个按键都有一个对应的键码值,这些值可以在 Android SDK 的 KeyEvent
类中找到。
示例代码
下面是一个简单的 Python 示例,展示了如何使用 press_keycode
来模拟按下某个按键:
from appium import webdriver# 配置Desired Capabilities
desired_caps = {'platformName': 'Android','deviceName': 'your_device_name','appPackage': 'your_app_package','appActivity': 'your_app_activity'
}# 初始化WebDriver
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)try:# 模拟按下返回键(键码为4)driver.press_keycode(4)print("Back button pressed")# 模拟按下Home键(键码为3)driver.press_keycode(3)print("Home button pressed")# 模拟按下音量加键(键码为24)driver.press_keycode(24)print("Volume up button pressed")# 模拟按下音量减键(键码为25)driver.press_keycode(25)print("Volume down button pressed")finally:# 结束会话driver.quit()
常用键码
以下是一些常用的 Android 键码及其对应的按键:
- 返回键:
4
- Home键:
3
- 菜单键:
82
- 音量增加:
24
- 音量减少:
25
- 电源键:
26
- 相机键:
27
- 搜索键:
84
传递额外参数
有时候你可能需要传递额外的参数,比如 metastate
(元状态),用于组合按键(如 Shift + A)。你可以通过传递额外的参数来实现这一点:
# 按下组合键(例如Shift+A)
driver.press_keycode(29, metastate=64) # 29 是 'A' 键,64 是左 Shift 键的状态
注意事项
- 确保设备连接:确保你的设备已经正确连接,并且可以通过
adb devices
命令识别到。 - 权限问题:某些按键(如电源键)可能需要特殊的权限或设备处于解锁状态才能正常工作。
- Appium 版本:确保你使用的 Appium 版本支持这些功能,某些旧版本可能不完全支持所有的按键操作。
iOS 设备
对于 iOS 设备,由于系统限制,直接模拟物理按键的功能较少。不过,你可以使用其他方法来实现类似的效果,例如通过 execute_script
方法执行特定的 JavaScript 脚本来触发某些行为。
获取通知栏并进行操作
在使用 Appium 进行移动应用自动化测试时,直接操作通知栏并不是其核心功能之一。不过,Appium 提供了一些方法来与设备的通知系统进行交互,特别是在 Android 设备上。对于 iOS 设备,由于系统的封闭性和限制,直接通过 Appium 操作通知栏的功能较为有限。
在 Android 上打开通知栏
在 Android 上,你可以使用 open_notifications()
方法来打开通知栏,并与其中的通知进行交互。以下是如何使用 Python 和 Appium 来实现这一功能的详细步骤和示例代码。
示例代码
下面是一个完整的示例,展示了如何使用 open_notifications
方法来打开通知栏,并与特定的通知进行交互:
from appium import webdriver# 配置Desired Capabilities
desired_caps = {'platformName': 'Android','deviceName': 'your_device_name','appPackage': 'your_app_package', # 如果需要启动一个特定的应用'appActivity': 'your_app_activity', # 如果需要启动一个特定的应用'noReset': True # 防止重置应用状态
}# 初始化WebDriver
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)try:# 打开通知栏driver.open_notifications()print("Notifications panel opened")# 查找并点击某个特定的通知(假设通知文本包含 "Your Notification Text")notification = driver.find_element_by_xpath('//android.widget.TextView[contains(@text, "Your Notification Text")]')notification.click()print("Notification clicked")# 可以在此处添加更多操作,比如验证是否正确跳转到目标页面等finally:# 结束会话driver.quit()
注意事项
-
确保通知存在:在尝试与通知交互之前,确保目标通知已经存在于通知栏中。可以通过手动触发通知或等待一段时间来确保通知已显示。
-
定位通知元素:通知栏中的元素可能具有动态内容,因此使用固定的资源ID可能不总是有效。通常情况下,可以使用文本内容(如上面示例中的 XPath)来定位通知。
-
权限问题:确保你的应用或测试脚本有足够的权限来访问通知栏。某些设备或系统版本可能需要额外的权限设置。
iOS 设备上的通知操作
对于 iOS 设备,由于系统的封闭性,直接通过 Appium 操作通知栏的功能非常有限。目前没有直接的方法可以通过 Appium 打开通知中心或与通知进行交互。不过,你仍然可以通过模拟用户的手势(例如从屏幕顶部向下滑动来打开通知中心),但这并不是直接操作通知的方式。
模拟手势打开通知中心(iOS)
尽管不能直接操作通知栏,但你可以尝试通过模拟手势来打开通知中心:
from appium.webdriver.common.touch_action import TouchAction# 创建TouchAction实例
action = TouchAction(driver)# 从屏幕顶部向下滑动来打开通知中心
action.press(x=100, y=50).move_to(x=100, y=500).release().perform()
请注意,这种方法的效果可能因设备型号、屏幕尺寸以及 iOS 版本的不同而有所差异。
总结
- Android:使用
driver.open_notifications()
方法可以直接打开通知栏,并通过标准的元素定位方法与通知进行交互。 - iOS:由于系统限制,无法直接通过 Appium 操作通知栏,但可以通过模拟手势来尝试打开通知中心。
相关文章:

App UI自动化--Appium学习--第二篇
如果第一篇在运行代码的时候出现问题,建议参考我的上一篇文章解决。 1、APP界面信息获取 adb logcat|grep -i displayed代码含义是获取当前应用的包名和界面名。 根据日志信息修改代码当中的包名和界面名,就可以跳转对应的界面。 2、界面元素获取 所…...
【SpringBoot实现全局API限频】 最佳实践
在 Spring Boot 中实现全局 API 限频(Rate Limiting)可以通过多种方式实现,这里推荐一个结合 拦截器 Redis 的分布式解决方案,适用于生产环境且具备良好的扩展性。 方案设计思路 核心目标:基于客户端标识(…...

Day1 25/2/14 FRI
【一周刷爆LeetCode,算法大神左神(左程云)耗时100天打造算法与数据结构基础到高级全家桶教程,直击BTAJ等一线大厂必问算法面试题真题详解(马士兵)】https://www.bilibili.com/video/BV13g41157hK?p3&v…...

开发板适配之I2C-RTC
rx8010时钟芯片挂载在I2C1总线上,并且集成在主控板上。 硬件原理 IOMUX配置 rx8010时钟芯片挂载在I2C1总线上,I2C1数据IIC1_SDA和时钟IIC1_SCL,分别对应的PAD NAME为,UART4_TX_DATA、UART4_RX_DATA。 在arch/arm/boot/dts/imx6u…...
vuedraggable固定某一item的记录
文章目录 基础用法第一种第二种 限制itemdiaggable重新排序交换移动的两个元素的次序每次都重置item的index 基础用法 第一种 <draggable v-model"list" :options"dragOptions"><div class"item" v-for"item in list" :key…...

我的新书《青少年Python趣学编程(微课视频版)》出版了!
🎉 激动人心的时刻来临啦! 🎉 小伙伴们久等了,我的第一本新书 《青少年Python趣学编程(微课视频版)》 正式出版啦! 📚✨ 在这个AI时代,市面上的Python书籍常常过于枯燥&…...

前端开发入门一
前端开发入门一 已经有若干年没有web相关的代码了,以前主要是用C/C编写传统的GUI程序,涉及界面、多线程、网络等知识点。最近准备开发一个浏览器插件,才发现业界已经换了天地,只得重新开始学习了,好在基本的学习能力还…...
Linux(Centos 7.6)命令详解:head
1.命令作用 将每个文件的前10行打印到标准输出(Print the first 10 lines of each FILE to standard output) 2.命令语法 Usage: head [OPTION]... [FILE]... 3.参数详解 OPTION: -c, --bytes[-]K,打印每个文件的前K字节-n, --lines[-],打印前K行而…...
HTTP请求X-Forwarded-For注入
场景描述 当你对用户网站进行的爆破或者sql注入的时候,为了防止你影响服务器的正常工作,会限制你访问,当你再次访问时,会提示你的由于你的访问频过快或者您的请求有攻击行为,限制访问几个小时内不能登陆,并且重定向到一个错误友好提示页面。 由此可以发起联想?http是无状…...

《生息之地》入围柏林主竞赛,总制片人蒋浩助力青年导演走向国际
当地时间2月13日,第75届柏林国际电影节正式开幕。凤凰传奇影业出品的电影《生息之地》已入围主竞赛单元,是本届电影节最受瞩目的华语作品之一,电影总制片人蒋浩、导演霍猛、监制姚晨等主创一同亮相开幕红毯。《生息之地》是导演霍猛继《过昭关…...

实践记录--电脑故障的问题定位和处理回顾--磁盘故障已解决
快速回顾 01-关于系统异常启动的展示信息,目前已经可以通过拍照翻译的方式辅助理解; 02-关于固态磁盘的故障定位,可以尝试通过SSD-Z工具查看分区引导记录信息,通过diskgenius工具进行坏道检测和修复; 03-体验了diskge…...

uni-app 学习(一)
一、环境搭建和运行 (一)创建项目 直接进行创建 (二)项目结构理解 pages 是页面 静态资源 打包文件,看我们想输出成什么格式 app.vue 页面的入口文件 main.js 是项目的入口文件 存放对打包文件的配置 pages 存放整…...
Ubuntu 22.04 Desktop企业级基础配置操作指南
一、网络配置 cd /etc/netplan vi 00-installer-config.yaml 设置如下所示: network:version: 2ethernets:eth0: # 替换为你的实际网络接口名称,如 ens33, enp0s3 等dhcp4: noaddresses:- 192.168.1.100/24 # 静态IP地址和子网掩码gateway4: 192.168.1.254 # 网关地址n…...
QILSTE H4-105LB/5M高亮蓝光LED灯珠 发光二极管LED
H4-105LB/5M:高亮蓝光LED的复杂特性与突发性挑战 在现代电子设备的复杂世界中,H4-105LB/5M型号的高亮蓝光LED以其独特的参数和复杂的特性脱颖而出。这款LED不仅在尺寸上做到了极致精巧,还在光电参数、可靠性测试和实际应用中展现出令人困惑的…...
【Elasticsearch】Elasticsearch检索方式全解析:从基础到实战(一)
文章目录 引言Elasticsearch检索方式概述两种检索方式介绍方式一:通过REST request uri发送搜索参数方式二:通过REST request body发送搜索参数(1)基本语法格式(2)返回部分字段(3)ma…...

封装neo4j的持久层和服务层
目录 持久层 mp 模仿: 1.抽取出通用的接口类 2.创建自定义的repository接口 服务层 mp 模仿: 1.抽取出一个IService通用服务类 2.创建ServiceImpl类实现IService接口 3.自定义的服务接口 4.创建自定义的服务类 工厂模式 为什么可以使用工厂…...

基于Spring Boot的宠物爱心组织管理系统的设计与实现(LW+源码+讲解)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
error: conflicting types for ‘SSL_SESSION_get_master_key’
$ make make all-am make[1]: Entering directory ‘/home/linuxuser/tor’ CC src/lib/tls/libtor_tls_a-tortls_openssl.o In file included from src/lib/tls/tortls_openssl.c:61: ./src/lib/tls/tortls_internal.h:55:8: error: conflicting types for ‘SSL_SESSION_get_…...

测试狗参加国家超级计算成都中心2024年度用户大会
近日,国家超级计算成都中心举办了“数启新篇算领未来”2024年度用户大会。这场盛会汇聚了来自政府部门、科研院所及企业界的百余位领导专家及用户代表,共同探讨高性能计算在科技创新中的赋能作用,探索超算融合领域的创新发展之路。其中&#…...
从2025年起:数字化建站PHP 8.1应成为建站开发的基准线
在数字化浪潮席卷全球的今天,PHP语言仍然保持着Web开发领域的核心地位。根据W3Techs最新统计,PHP驱动着全球78.9%的已知服务端网站。当时间指向2025年,这个拥有28年历史的编程语言将迎来新的发展里程碑——PHP 8.1版本应成为网站开发的最低基准要求,这不仅是技术迭代的必然…...

MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...

【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...
Qt Quick Controls模块功能及架构
Qt Quick Controls是Qt Quick的一个附加模块,提供了一套用于构建完整用户界面的UI控件。在Qt 6.0中,这个模块经历了重大重构和改进。 一、主要功能和特点 1. 架构重构 完全重写了底层架构,与Qt Quick更紧密集成 移除了对Qt Widgets的依赖&…...
在Spring Boot中集成RabbitMQ的完整指南
前言 在现代微服务架构中,消息队列(Message Queue)是实现异步通信、解耦系统组件的重要工具。RabbitMQ 是一个流行的消息中间件,支持多种消息协议,具有高可靠性和可扩展性。 本博客将详细介绍如何在 Spring Boot 项目…...
Python爬虫(四):PyQuery 框架
PyQuery 框架详解与对比 BeautifulSoup 第一部分:PyQuery 框架介绍 1. PyQuery 是什么? PyQuery 是一个 Python 的 HTML/XML 解析库,它采用了 jQuery 的语法风格,让开发者能够用类似前端 jQuery 的方式处理文档解析。它的核心特…...