appium(uiautomator与appium的区别)

本文目录
uiautomator与appium的区别
uiautomator和appium都作为移动端自动化测试的工具.那么他们有什么区别呢?
1.适用场景不同
uiautomator适用于adroid手机端自动化测试.而appium不仅适用于Android手机,同样适用于ios手机.
2.作用域不同
在Android系统场景中,uiautomator可跨app,在手机ROM层面实现交互.而appium只适合在应用内部,不能跨app.
而且appium可以实现webview界面的自动化测试,而uiautomator却不能.
3.原理
appium是通过webDriver调起应用,以appium server作为桥梁,通过Bootstrap.jar调用的android端uiautomator命令和ios端uiautomation/XCTest(ios 8以上).
uiautomator通过android instrumentation获取系统上下文,设备信息状态等.
appium具有的三个功能
Appium的功能实际上是一系列JSON对象(一组键-值对),客户端将所需的能力发送给服务器。接下来,我们来逐一描述一下能力。首先,让我们看看Appium服务的功能:为了使java和期望的功能一起工作,我们需要导入。“import org . open QA . selenium . remote . desired capabilities”函数库。基本依赖性Appium真正的工作引擎是第三方自动化框架。使用以下第三方框架:-iOS:苹果的UIAutomation- Android 4.2+:谷歌的UiAutomator-Android 2.3+:谷歌的仪表化。(仪器由单独的项目Selendroid支持)-第三方软件包,如Selenium Web Driver。
读懂appium原理,看这篇就够了
话不多说,直接上干货:
appium的整体架构是C/S模式,整体流程(返回顺序为逆向):
脚本请求 ——》 4723端口appium server ——》 解析参数给PC端4724端口 ——》 发送给设备4724端口 ——》 通过设备4724端口发给bootstrap.jar ——》 Bootstrap.jar把命令发给uiautomator
1、脚本请求 ——》 4723端口appium server :
首先我们要开启appium服务,即Appium server,也就是在命令行用appium命令打开的东西,默认监听4723端口。4723端口专门和脚本打交道,基于WebDriver协议。webdriver是按照server – client的经典设计模式设计的,作用就是启动基于WebDriver Wire协议的appium服务,接下来脚本与appium server的通信实际上是一个HTTP request请求给appium server,在请求的body中,会以WebDriver Wire协议规定的 JSON 格式的字符串来告诉appium服务我们希望设备接下来做什么事情。读到这里,难免有同学会有疑问了,因为有一些文档上面说脚本发送请求是基于Json wire protocol协议的,首先这是完全正确的,接下来就解释一下:
appium中的Json wire protocol继承自selenium的webdriver wire protocol,并进行了扩展,使得Json wire protocol能够控制不同的移动设备的行为。如果大家觉得对于webdriver这个名词觉得比较陌生的话,接下来说一个词肯定熟悉 - Selenium。Selenium是一个浏览器自动化操作框架。Selenium主要由三种工具组成。第一个工具SeleniumIDE,是Firefox的扩展插件,支持用户录制和回访测试,录制/回访模式存在局限性,对许多用户来说并不适合,因此第二个工具——Selenium WebDriver提供了各种语言环境的API来支持更多控制权和编写符合标准软件开发实践的应用程序。最后一个工具——SeleniumGrid帮助工程师使用Selenium API控制分布在一系列机器上的浏览器实例,支持并发运行更多测试。在项目内部,它们分别被称为“IDE”、“WebDriver”和“Grid”。
那么webdriver wire protocol又是什么呢:
在我们创建一个WebDriver的过程中,Selenium首先会确认浏览器的native component是否存在可用而且版本匹配。接着就在目标浏览器里启动一整套Web Service,这套Web Service使用了Selenium自己设计定义的协议,名字叫做 The WebDriver Wire Protocol, 只不过对应到我们这里的浏览器指的是Appium。
WebDriver Wire协议是通用的,也就是说不管是FirefoxDriver还是ChromeDriver,启动之后都会在某一个端口启动基于这套协议的Web Service。对应到Appium,可以理解为是AppiumDriver。接下来,我们调用WebDriver的任何API,都需要借助一个 ComandExecutor 发送一个命令,实际上是一个HTTP request给端口上的Web Service。在我们的HTTP request的body中,会以WebDriver Wire协议规定的 JSON 格式的字符串来告诉Selenium我们希望浏览器(设备)接下来做什么事情。
说到这里可能会有疑问了,上面说到的是脚本请求对设备进行操作,但前提是,我们要对谁进行操作测试呢?这里就引入一个新名词:desiredCapabilities。了解了上述之后,再去看脚本怎么将desiredCapabilities传递给appium server就明白多了,脚本通过Json Wire Protocol协议以json格式发送测试设备信息给server端,测试设备信息被携带在Desired Capabilities中,这个东西实质上是一个key-value形式的对象,Desired Capabilities最重要的作用是告诉server本次测试的上下文。这次是要进行浏览器测试还是移动端测试?如果是移动端测试的话是android还是ios?如果android的话我们要测试哪个app?server的这些疑问Desired Capabilities都必须给予解答,否则server不买账,针对我们现在所说的安卓,它带来的影响就是无法完成app的启动。
***隐藏网址***
Session在计算机中,尤其是在网络应用中,称为“会话控制”。Session 对象存储特定用户会话所需的属性及配置信息,对应到这里其实就是desiredCapabilities中的配置信息参数。脚本通过POST /session这个URL,然后传入Desired Capabilities就可以开启session了,由于这是第一次请求创建session,所有并没有一个已创建的session id,所以appium server会调用android driver(appium升级到2.0.0后,原有的AppiumDriver函数变成抽象函数了,需更改为AndroidDriver)为client生成一个session并且生成一个与此session相关联的session id,这个 session id将被在本次响应中返回给客户端保存,当下次脚本发出操作请求时就会自带session id为唯一标识,代表所打开的设备,Appium server会按照此session id把这个session检索出来使用,脚本向appium server发送的请求即是存在于创建的session中的。
Session 的作用就是它在appium服务上保持设备的状态信息,供在任何时间进行访问,在多次的操作行为中,存储在 Session对象中的配置信息将不会丢失,而是在整个用户会话中一直存在下去,整个测试进程中设备与程序的联系不会断开,也不需要每次都发送带配置信息的请求,程序都知道对哪个设备进行测试操作。当测试结束后,需关闭webdriver,driver.quit()会关闭所有关联窗口和session,并且也会把进程也关闭。
2、解析参数给PC端4724端口 ——》 发送给设备4724端口 ——》 通过设备4724端口发给bootstrap.jar ——》 Bootstrap.jar把命令发给uiautomator:
创建session成功之前,就已将bootstrap.jar放入手机中,并开启设备上的基于appium bootstrap的socket服务,绑定本机和boostrap通信的端口号4724用于和Android设备通讯,默认监听4724端口,等待client的连接。
Appium server将脚本的请求解析后给到4724端口,通过设备的4724端口转发解析后的请求, 此时,对于socket服务来说,appium server就充当了client的角色,appium server通过4724端口主动去请求设备上的socket服务,即向socket服务发送请求,即bootstrap.jar,Bootstrap.jar再把Appium的命令转换成uiautomator的命令来让uiautomator进行处理。有请求就有返回,socket接收到请求后会做出响应,原路返回给脚本,然后脚本再进行下一次的请求。
网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。appium和手机的通信过程,主要是数据交换的一个过程,socket的作用是就是为了实现双向通信,它需要一对端口号,对应到这里就是4724,手机端的bootstrap就是socket-server端,appium server就是socket-client端。
关于socket的通信原理,先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。
appium滑动操作总结
经常有人说appium的滑动实现是门艺术,实现不好就会出现事与愿违的操作,比如本来想要向上滑动,却出现了下拉的动作,这样使得我们在调试中就要花费大量时间去调试滑动操作。
以下是我在滑动操作中总结的一点经验,希望可以对遇到这方面问题的读者有一点帮助;
总结:
1、滑动时中间要加等待时间,不加等待时间容易出错,而且加等待时间的长短也要掌握好,一般在200-1000毫秒之间应该差不多,自己调试几次感觉一下哪个时间比较稳,每个程序可能会有所差异,还要注意的是ios和Android的等待时间也会有差异,ios等待1000毫秒可能出现长安的效果;
TouchAction tAction = new TouchAction(driver);
tAction.press(x,y).waitAction(200).moveTo(x,y).release().perform();
2、滑动的坐标点,滑动的坐标点要掌握好,如果坐标点掌握不好也会导致错误出现,比如Android和ios就有很大区别,以下示例分别是ios和Android实现上滑动作;
Android实现上滑:
int width=driver.manage().window().getSize().width;
int height=driver.manage().window().getSize().height;
int y1 = height*3/4; //上滑的开始点,从y1开始也就是屏幕的四分之三处
int y2 = height*1/4; //上滑的结束点,到y2结束也就是屏幕的四分之一处
TouchAction tAction = new TouchAction(driver);
tAction.press(width/2,y1).waitAction(200).moveTo(width/2,y2).release().perform();
ios实现上滑:
tAction.press(width/2,y1).waitAction(200).moveTo(width/2,y2-y1).release().perform();
解释:
比如总高度是1600,那么y1就是1200,y2是400,高度从1200移动到400的位置,这个大家应该都能理解,而ios的结束点的高度坐标是y2-y1,这样得出的是一个负数,这样感觉不太容易理解,这个可能是他们的算法有差异;我理解ios滑动算法是,y2-y1=-800,然后y1是1200,y1移动到y2,就是y1+y2=400,就是说移动到400的位置,这样理解感觉也能说的通,当然只是我自己的理解,如有更好见解欢迎讨论。

更多文章:
影视剧中有哪些剧情颠覆了你的三观?金庸的武侠小说《白马啸西风》为什么没有被拍成电影或者电视剧
2026年9月7日 00:30
mysql varchar和char的区别(mysql中char、varchar、nvarchar区别)
2026年9月7日 00:10
linux命令的选项和参数(linux为什么要有参数和选项)
2026年9月6日 20:20
perseverance的意思(preseverance的意思)
2026年9月6日 18:30
react native和uniapp(h5和uniapp和react性能)
2026年9月6日 18:00
mysql查看有哪些表(在mysql里面怎么查看数据库里面有多少表)
2026年9月6日 17:40
parsefloat()(html里的parsefloat什嘛意思)
2026年9月6日 16:30
onreceive函数(Android怎么给onReceive()函数传参数)
2026年9月6日 15:00
school day是什么意思(school days为什么要翻译成日在校园啊)
2026年9月6日 14:10

