Appium(四)

news2025/1/22 11:59:05

一、app页面元素定位

  1、通过id定位元素: resrouce-id
  2、通过ClassName定位:classname
  3、通过AccessibilityId定位:content-desc
  4、通过AndroidUiAutomator定位
  5、通过xpath定位

  xpath、id、class、accessibility id、android uiautomator



  UI Automator
  UI自动化测试框架,安卓移动端app
  要求:Android 4.3以上
  提供了一系列API:执行UI测试在系统或者第三方app上面
  允许在被测设备上执行操作,比如打开系统设置菜单
  适合编写黑盒自动化测试

  UI Automator框架的主要特点:
  1、元素定位:UI Automator Viewer:扫描、分析待测应用的UI组件的图像工具。
  2、元素操作:Accessing device state:在目标设备和app上的各种操作
  3、元素识别:UI Automator APIs:在多个应用程序中捕获和操作UI组件
  
  使用UIAutomator中的UiSeletor类来处理元素定位
  在python客户端appium库中通过,uiautomator来获取元素的方法为:
  driver.find_elements_by_android_uiautomator()

  该方法的参数为UiSeletor类定位元素的表达式:
  new UiSelector().函数名称("定位表达式")
  实例化一个UiSeltctor对象,然后通过示例调用接口
  示例:
  需要导入包:
  from appium.webdriver.common.appiumby import AppiumBy
  driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,'new UiSelector().resourceId("com.tencent.mobileqq:id/dialogLeftBtn")')

二、滑动屏幕

滑动接口:
swipe(起始X,起始Y,结束X,结束Y)
结束X-起始X:X轴滑动的距离
结束Y-起始Y:Y轴滑动的距离

手机的屏幕尺寸有很多,如何兼容?
get_window_size()  获取屏幕大小,返回的是一个字典
如:
size=driver.get_window_size()
print(size)
返回的结果为:
{'width': 1080, 'height': 1920}
# 滑屏操作
# get_window_size()  获取屏幕大小,返回的是一个字典
size=driver.get_window_size()
# 向右滑屏
driver.swipe(size["width"]*0.8,size["height"]*0.5,size["width"]*0.2,size["height"]*0.5,100)
sleep(2)
print("滑屏到热点")

三、appium----模拟触屏

TouchAction类(从Appium2.0 TouchAction被弃用)
将一些列的动作放在一个链条中,然后将该链条传递给服务器。服务器接收到该链条后,解析各个动作,逐个执行。
短按(press)
长按(longPress)
点击(tap)
移动到(move_to)  x,y为相对上一个坐标的移动距离
等待(wait)
释放(release)
执行(perform)
取消(cancel)

在这里插入图片描述

from appium.webdriver.common.touch_action import TouchAction
ele=driver.get_element(AppiumBy.ID,"")
# 元素的大小  返回的是一个字典{"width":xxx,"height":xxx}
size=ele.size
# 正方形 所以宽高的步长一样
step=size["width"]/6
# 元素的起始坐标-左上角
ori=ele.location
point1=(ori["x"]+step,ori["y"]+step)
point2=(point1[0]+step*2,point1[1]) # 相对于point1,x轴增加了2*step
point3=(point2[1]+step*2,point2[1]) # 相对于point2,x轴增加了2*step
point4=(point3[1]-step*2,point3[1]+step*2) # 相对于point3,x轴减少了2*step,y轴增加了2*step
point5=(point4[1],point4[1]+step*2) # 相对于point3,x轴不变,y轴增加了2*step

TouchAction(driver).press(x=point1[0],y=point1[1]).wait(200).\
    move_to(x=point2[0],y=point2[1]).wait(200).\
    move_to(x=point3[0],y=point3[1]).wait(200).\
    move_to(x=point4[0],y=point4[1]).wait(200).\
    move_to(x=point5[0],y=point5[1]).wait(200).\
    release().\
    perform()

appium-python-client的版本为4.0.1,这个版本中,好像没有touchaction的包,因此,使用w3c来代替操作
from selenium.webdriver import ActionChains
1、实例化:
从之前的action = TouchAction(driver)改为
action = ActionChains(driver)
2、按压操作
从之前的action.press()改为:
action.w3c_actions.pointer_action.click_and_hold()
3、等待操作
从之前的action.wait()改为:
action.w3c_actions.pointer_action.pause(2)
4、释放操作:
从之前的action.release()改为:
action.w3c_actions.pointer_action.release()
5、执行操作不变,依旧为action.perform()。

四、Toast消息提示框

Toast是一种简易的消息提示框,通常用于向用户显示信息。Toast消息不能被用户点击,并且会根据所设置的显示时间自动消失。
不会获得焦点,无法被点击,并且显示时间有限,一般会在几秒内自动消失。
Toast消息通常用于提示用户某些操作的结果或状态,例如密码输错后的提示。

 要获取Toast信息要满足
Appium对Toast的支持‌:
(1)Appium从1.6.3版本开始支持识别Toast内容,这主要是基于UiAutomator2的。因此,在使用Appium获取Toast消息时,需要在Capability配置中添加参数'automationName': 'UIAutomator2'
(2)UIAutomator2只支持安卓5.0以上的版本

xpath表达式:
xpath="//*[contains(@text,'文本内容')]"
注意:driverWait方法中,请用presence_of_element_located,不要用visibility_of_element_located,对toast的可见处理并不支持,会直接报错命令无法执行

在这里插入图片描述

from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from time import sleep
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
desired_caps={
  "deviceName": "127.0.0.1:5555",
  "platformName": "Android",
  "platformVersion": "7.1.2",
  "appPackage": "com.ss.android.article.news",
  "appActivity": ".activity.MainActivity",
  "automationName":"UiAutomator2"
}
# 连接appium server。前提:appium desktop要启动。有监听窗口
# 将desired_caps发送给appium server。打开app

driver=webdriver.Remote("http://127.0.0.1:4723/wd/hub",desired_caps)
# 运行代码之前:
# 1、appium server启动成功。处于监听状态;
# 2:模拟器/真机必须能够被电脑识别。即adb devices能够识别到要操作的设备。
# 通过resource-id定位
# 等待进入首页,看到推荐
WebDriverWait(driver,20).until(
    EC.visibility_of_element_located((AppiumBy.ACCESSIBILITY_ID,"推荐"))
)
print("可以看到推荐")
# 进行登录操作
driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,'new UiSelector().text("未登录").resourceId("com.ss.android.article.news:id/ctd")').click()
sleep(0.5)
# 等待登录页面出现
WebDriverWait(driver,20).until(
    EC.visibility_of_element_located((AppiumBy.ID,"com.ss.android.article.news:id/ctb"))
)
driver.find_element(AppiumBy.ID,"com.ss.android.article.news:id/c04").click()
sleep(0.5)
# 找到账号密码登录
WebDriverWait(driver,20).until(
    EC.visibility_of_element_located((AppiumBy.ID,"com.ss.android.article.news:id/ro"))
)
driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,'new UiSelector().text("密码登录").resourceId("com.ss.android.article.news:id/bhu")').click()
sleep(0.5)
# 进入账号密码登录页面
WebDriverWait(driver,20).until(
    EC.visibility_of_element_located((AppiumBy.ID,"com.ss.android.article.news:id/bhh"))
)
driver.find_element(AppiumBy.ID,"com.ss.android.article.news:id/bhh").send_keys("18435990207")
driver.find_element(AppiumBy.ID,"com.ss.android.article.news:id/bhp").send_keys("123")
driver.find_element(AppiumBy.ID,"com.ss.android.article.news:id/qa").click()
sleep(0.5)
xpath='//*[contains(@text,"访问太")]'
try:
    WebDriverWait(driver,10,0.02).until(
    EC.presence_of_element_located((AppiumBy.XPATH,xpath))
    )
    print(driver.find_element(AppiumBy.XPATH,xpath).text)
except:
    print("没有找到Toast")


运行结果:访问太频繁,请稍后再试

五、混合应用-H5

目前主流用用程序分为三类:Web App(网页应用)、Hybrid App(混合应用)、Native App(原生应用)

怎么样分辨一个app页面究竟是native还是web的?
1、在手机/模拟器中点击手机号的版本号5下,进入开发者选项
2、在开发者选项中勾选上显示布局边界,再返回到App界面
3、如果App是web的界面,那界面不会有布局边界显示,如有则说明是native的界面
或者通过定位工具  点中间没有原生部件的地方,看class值

在这里插入图片描述

基于UIAutomator+Chromedriver
native部分则uiautomator,webview部分走chromedriver,二者结合要求:
android 4.4+
webview必须为debug版本

获取webview页面的三种方式:
1、chrome://inspect,需要翻墙
2、使用driver.page_source获取html页面
3、找开发人员要源文件
4、uc-devtools   不需要翻墙(推荐)

常见问题:
contexts只能获取NATIVE_APP ,无法获取WEBVIEW
使用uiautomatorviewer定位元素,显示class值为:android.webkit.WebView
但是driver.contexts只打印出‘NATIVE_APP’

解决方法:
1、app打包的时候需要开发webview的debug属性setWebContentDebuggingEnableed(true),这个直接让开发加上就好
2、模拟器的有些contexts中有webdriver,但有些手机没有。
官方给出的答案是:需要将手机root,然后再去获取。

开启webview可见:
https://developers.google.com/web/tools/chrome-devtools/remote-debugging/webviews

上下文切换:
可用的上下文(Contexts)
列出所有可用的上下文(contexts)
driver.contexts

driver.window_handles
当前上下文(Context):列出当前的上下文
driver.current_context

切换到默认的上下文(Context)
切换回默认的上下文(Context)。(一般就是原生上下文"NATIVE_APP")
driver.switch_to.context(None)

当前Activity:获取当前的Activity。仅支持Android
driver.current_activity

当前包名(package):获取当前包名(package)。仅支持Android
driver.current_package

在这里插入图片描述
在这里插入图片描述

如果出现这种情况,这好换Appium版本
在这里插入图片描述

关注:https://www.cnblogs.com/yyoba/p/9455519.html

小程序

在这里插入图片描述

http://www.lemfix.com/topics/83 APP自动化 appium+pytest+allure+jenkins 如何实现多台手机连接
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Windows图形界面(GUI)-QT-C/C++ - Qt List Widget详解与应用

公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 目录 QListWidget概述 使用场景 常见样式 QListWidget属性设置 显示方式 (Display) 交互行为 (Interaction) 高级功能 (Advanced) QListWidget常见操作 内容处理 增加项目 删除项目…

Oracle 创建并使用外部表

目录 一. 什么是外部表二. 创建外部表所在的文件夹对象三. 授予访问外部表文件夹的权限3.1 DBA用户授予普通用户访问外部表文件夹的权限3.2 授予Win10上的Oracle用户访问桌面文件夹的权限 四. 普通用户创建外部表五. 查询六. 删除 一. 什么是外部表 在 Oracle 数据库中&#x…

靠右行驶数学建模分析(2014MCM美赛A题)

笔记 题目 要求分析: 比较规则的性能,分为light和heavy两种情况,性能指的是 a.流量与安全 b. 速度限制等分析左侧驾驶分析智能系统 论文 参考论文 两类规则分析 靠右行驶(第一条)2. 无限制(去掉了第一条…

Kafka 源码分析(一) 日志段

首先我们的 kafka 的消息本身是存储在日志段中的, 对应的源码是下面这段代码: class LogSegment private[log] (val log: FileRecords,val lazyOffsetIndex: LazyIndex[OffsetIndex],val lazyTimeIndex: LazyIndex[TimeIndex],val txnIndex: TransactionIndex,val baseOffset:…

【番外篇】实现排列组合算法(Java版)

一、说明 在牛客网的很多算法试题中,很多试题底层都是基于排列组合算法实现的,比如最优解、最大值等常见问题。排列组合算法有一定的难度,并不能用一般的多重嵌套循环解决,没有提前做针对性的学习和研究,考试时候肯定…

Linux - 线程池

线程池 什么是池? 池化技术的核心就是"提前准备并重复利用资源". 减少资源创建和销毁的成本. 那么线程池就是提前准备好一些线程, 当有任务来临时, 就可以直接交给这些线程运行, 当线程完成这些任务后, 并不会被销毁, 而是继续等待任务. 那么这些线程在程序运行过程…

【K8S系列】K8s 领域深度剖析:年度技术、工具与实战总结

引言 Kubernetes作为容器编排领域的行业标准,在过去一年里持续进化,深刻推动着云原生应用开发与部署模式的革新。本文我将深入总结在使用K8s特定技术领域的进展,分享在过去一年中相关技术工具及平台的使用体会,并展示基于K8s的技术…

C++《AVL树》

在之前的学习当中我们已经了解了二叉搜索树,并且我们知道二叉搜索树的查找效率是无法满足我们的要求,当二叉树为左或者右斜树查找的效率就很低下了,那么这本篇当中我们就要来学习对二叉搜索树进行优化的二叉树——AVL树。在此会先来了解AVL树…

【MySQL】存储引擎有哪些?区别是什么?

频率难度60%⭐⭐⭐⭐ 这个问题其实难度并不是很大,只是涉及到的相关知识比较繁杂,比如事务、锁机制等等,都和存储引擎有关系。有时还会根据场景选择不同的存储引擎。 下面笔者将会根据几个部分尽可能地讲清楚 MySQL 中的存储引擎&#xff0…

王道数据结构day1

2.1线性表的定义和基本操作 1.线性表的定义 相同数据类型的数据元素的有限序列 位序(从1开始) 表头元素,表尾元素 直接钱去,直接后继 2.线性表的基本操作 基本操作:创销,增删改查 优化插入: 查找

电梯系统的UML文档07

从这个类中得到的类图,构划出了软件的大部分设计。 系统结构视图提供软件和整个系统结构最复杂的也是最优雅的描述。和通常的软件系统相比,在分布式嵌入系统中了解系统组件如何协同工作是非常重要的。毕竟,每个类图仅仅是一个系统的静态设计…

数据恢复常见故障(五)晶振异常导致时钟Clock信号异常引发的硬盘故障

晶振是给固态硬盘“主控”芯片工作提供时钟信号的器件。 高温、高湿、撞件等都会引起晶振不起振,最终导致时钟信号异常。 如图是正常情况下的晶振波形。 晶振异常时,输出的波形,不起振。 由于晶振异常,无法提供时钟信号&#…

16.5万煤气柜柜位计故障分析

一、事故经过: 2015年8月14日20点45分,16.5万立煤气柜柜顶油封溢流口有大量油液溢出,此时雷达柜位计在计算机上示值为63.79米,由于接近傍晚天色较暗,岗位操作员并未及时发现这一异常状况。22点45分左右&…

ARM学习(42)CortexM3/M4 MPU配置

笔者之前学习过CortexR5的MPU配置,现在学习一下CortexM3/M4 MPU配置 1、背景介绍 笔者在工作中遇到NXP MPU在访问异常地址时,就会出现总线挂死,所以需要MPU抓住异常,就需要配置MPU。具体背景情况可以参考ARM学习(41)NXP MCU总线挂死,CPU could not be halted以及无法连…

STM32 FreeRTOS 任务挂起和恢复---实验

实验目标 学会vTaskSuspend( )、vTaskResume( ) 任务挂起与恢复相关API函数使用: start_task:用来创建其他的三个任务。 task1:实现LED1每500ms闪烁一次。 task2:实现LED2每500ms闪烁一次。 task3:判断按键按下逻辑,KE…

七.网络模型

最小(支撑)树问题 最小部分树求解: 破圈法:任取一圈,去掉圈中最长边,直到无圈; 加边法:取图G的n个孤立点{v1,v2,…, vn }作为一个支撑图,从最短…

web前端1--基础

(时隔数月我又来写笔记啦~) 1、下载vscode 1、官网下载:Visual Studio Code - Code Editing. Redefined 2、步骤: 1、点击同意 一直下一步 勾一个创建桌面快捷方式 在一直下一步 2、在桌面新建文件夹 拖到vscode图标上 打开v…

麦田物语学习笔记:保存和加载场景中的物品

目录 基本流程 1.代码思路 2.代码实现 最终效果 补充知识点 1.序列化 2.委托 基本流程 现在在切换场景后,场景中的物品即使被拾取了,也还是会被重新加载出来,所以本篇文章的任务是在切换场景前后能保留当前场景的数据 1.代码思路 (1)为了保留处在地上的物品数据,就需要…

51c~SLAM~合集1

我自己的原文哦~ https://blog.51cto.com/whaosoft/12327374 #GSLAM 自动驾驶相关~~~ 一个通用的SLAM架构和基准 GSLAM:A General SLAM Framework and Benchmark 开源代码:https://github.com/zdzhaoyong/GSLAM SLAM技术最近取得了许多成功&am…

QT调用OpenSceneGraph

OSG和osgQt编译教程,实测通过 一、下载OpenSceneGraph OpenSceneGraphhttps://github.com/openscenegraph/OpenSceneGraph 二、使用CMAKE编译OpenSceneGraph 1.打开cmake,配置源代码目录 2. CMAKE_INSTALL_PREFIX设置为install文件夹,生…