Appium Uiautomator2 Server源码调试指南

appium-uiautomator2-server 是Appium在安卓端实现自动化能力的核心,上层脚本的所有操作,最终都转换成基于 appium-uiautomator2-server 提供的HTTP接口进行调用。本篇讲述该模块的调试方法,帮助读者更好的理解Appium在安卓上是如何实现自动化的。

本文配套工程链接

1.uiautomator与uiautomator2-server的关系

UI Automator 是google官方提供的一个用于编写自动化测试的官方库,其优势主要为:

官方目前大力支持的框架之一(另外一个是Expresso),

基于安卓原生控件解析,比坐标类型的兼容性更好

提供了丰富的等待机制

不依赖源码(纯黑盒)

可以跨应用。

市面上的诸多安卓测试工具(Appium,Minitest,ATX)等基本都绕不开对uiautomator库的依赖。

但如果直接使用uiautomator进行自动化测试,需要编写原生的java或kotlin代码,成本较高。uiautomator2-server的作用,就是对uiautomator的API做进一步的封装,将UI自动化常用的操作,通过HTTP接口的方式提供出来。使用者只需要把Appium Uiautomator2 Server在手机上运行起来,就可以通过给它发送各种HTTP请求,驱动自动化流程的进行。也正是得益于uiautomator2-server这层HTTP服务封装,Appium的上层脚本才可以支持多种编程语言(Ruby,Python,JS,Java),最终都会把上层业务的各种指令转换成uiautomator2-server的接口请求。

为方便学习,本文配套工程链接 以源代码形式引入了uiautomator,在config.gradle文件中,将useRemoteSDKLibrary设置为false即为源码依赖模式。

2.调试Appium自带的APK

Appium官方针对Appium Uiautomator2 Server编写了一系列的E2E测试代码,并提供了一个单独的APK。

测试工程将该apk文件放到了项目的目录下,并修改了运行脚本。

androidTest目录下的用例,可以直接点红框的按钮运行起来。覆盖了Appium Uiautomator2 Server基本的接口调用。

也可以在代码中设置断点,以debug的方式单步调试运行。

3.调试设备上的其他应用

由于Appium Uiautomator2 Server编写的E2E测试代码,会默认拉起ApiDemos-debug.apk应用。如果期望验证其他的应用,可以通过设置 配置文件 中的 runApiDemoApk 字段为false。

后续的E2E测试用例将不再拉起默认的应用,可以自己编写针对目标App的测试代码。

4.基于HTTP请求的方式运行Appium Uiautomator2 Server

(1) 打包Appium Uiautomator2 Server 工程

在项目根目录下运行打包命令:

bash 复制代码
./gradlew clean assembleServerDebug assembleServerDebugAndroidTest

注意打包环境的jdk版本必须>=11以上,最终的打包产物为如下的两个apk:

正式安装之前,可以将之前的e2e相关测试apk卸载掉,执行如下命令:

lua 复制代码
adb uninstall io.appium.uiautomator2.server.test
adb uninstall io.appium.uiautomator2.server
adb uninstall io.appium.uiautomator2.e2etest.test
adb uninstall io.appium.uiautomator2.e2etest
adb uninstall io.appium.espressoserver.test

之后通过 adb install -r 将上面的两个产物apk完成路径拼入,执行安装即可。

(2) 启动 Appium Uiautomator2 Server 服务

step1:本地先做端口转发:

adb forward tcp:65272 tcp:6790

其中 65272 可以换为其他的端口号,不冲突即可。

step2:控制台基于instrument启动服务

bash 复制代码
adb shell am instrument -w io.appium.uiautomator2.server.test/androidx.test.runner.AndroidJUnitRunner

(3) 给服务发送请求

(1) 建立连接

json 复制代码
curl -d '{"capabilities":{}}' -X POST "http://127.0.0.1:65272/session"

返回:

erlang 复制代码
{"sessionId":"ccf6f9e5-4e53-41a3-8212-61ba80a23ed4","value":{"capabilities":{},"sessionId":"ccf6f9e5-4e53-41a3-8212-61ba80a23ed4"}}%

表示成功建立了一个会话连接请求。

这里定义变量记录下sessionID,方便后续进一步的调试

ini 复制代码
CUR_SESSION_ID='ccf6f9e5-4e53-41a3-8212-61ba80a23ed4'

(2) 获取视图操作

bash 复制代码
curl -X GET "http://127.0.0.1:65272/session/$CUR_SESSION_ID/source"

输出即为当前界面的完整xml结构。

(3) 滑动操作

json 复制代码
curl -d '{"endY":200,"endX":540,"startY":1710,"startX":540,"steps":100}' -X POST "http://127.0.0.1:65272/session/$CUR_SESSION_ID/touch/perform"

触发一个滑动的操作,[startX, startY][endX,endY] 分别表示滑动手势的开始位置与结束位置。step用于控制滑动操作整体的耗时。steps设置为100表示在0.5秒内完成。

(4) 查找操作

json 复制代码
curl -d '{"selector":"更多信息","strategy":"accessibility id"}' -X POST "http://127.0.0.1:65272/session/$CUR_SESSION_ID/elements"

会查找当前界面 accessibility id更多信息的元素,结果为:

erlang 复制代码
{"sessionId":"ccf6f9e5-4e53-41a3-8212-61ba80a23ed4","value":[{"ELEMENT":"00000000-0000-03af-ffff-ffff0000039a","element-6066-11e4-a52e-4f735466cecf":"00000000-0000-03af-ffff-ffff0000039a"}]}%

value部分为一个数组,表示查找到了目标元素信息。可以把元素id缓存起来:

ini 复制代码
CUR_ELELMENT_ID='00000000-0000-03af-ffff-ffff0000039a'

之后基于元素id,实现点击的操作:

bash 复制代码
curl -X POST "http://127.0.0.1:65272/session/$CUR_SESSION_ID/element/$CUR_ELELMENT_ID/click"

当前界面 accessibility id更多信息的元素就会被点击。

(5) 其他更多操作

Appium-Server的所有接口定义,均在AppiumServlet.java 文件中,按照上述的思路,拼接指定的参数,即可完成各个操作的测试流程。

5.参考

1. 使用 UI Automator 编写自动化测试

2. AndroidX UI Automator 代码库

相关推荐
大柏怎么被偷了13 小时前
【软件测试】测试的岗位有哪些?
软件测试·测试
革斤要加油6 天前
测试开发基础——软件测试中的bug
bug·测试
Amd79410 天前
使用 nuxi upgrade 升级现有nuxt项目版本
测试·开发·命令·升级·nuxt 3·nuxi·项目创建
bug菌¹14 天前
滚雪球学MyBatis-Plus(13):测试与部署
部署·测试·mybatis-plus·零基础入门教学
开测开测20 天前
day31-测试之性能测试工具JMeter的功能概要、元件作用域和执行顺序
测试开发·测试工具·jmeter·单元测试·压力测试·性能测试·测试
开测开测22 天前
day35-测试之性能测试JMeter的测试报告、并发数计算和性能监控
测试开发·测试工具·jmeter·压力测试·性能测试·测试·监控
small_snowball24 天前
三种自动化测试(接口自动化,UI 自动化,单元测试)保姆级教程
java-ee·测试
让开,我要吃人了25 天前
OpenHarmony实战开发: unittest单元测试的编写
linux·华为·log4j·移动开发·测试·harmonyos·鸿蒙
多则惑少则明1 个月前
软件测试第1章 软件测试是什么
测试·测试与质量保证
Serendipity_筱楠1 个月前
解决Pytest UnknownMarkWarning: Unknown pytest.mark.single - is this a typo?
python·pytest·测试