Appium UiAutomator2驱动:Settings A
一、什么是Settings API
Appium
的UiAutomator2
驱动支持各种能力参数,在创建客户端和服务端会话的时候,以键值对的方式进行协商。当会话建立之后,如何对这些能力参数进行调整呢?
针对上述场景的需要,Appium
引入了一系列的扩展API
接口,允许在会话建立后,在执行过程中对参数(能力)进行调整。这些API
接口统称为Settings API
,被改动的参数称为Settings
。
Settings
有三个重点的概念:
-
Settings
是可变的,会话期间可以通过Settings API
接口进行更改; -
Settings
只跟会话期间设置的内容相关,通常新的会话需要重新设置,但是借助某些驱动,一些设置可以在会话之间保持; -
Settings
只是调整测试期间Appium
服务端的行为,而不涉及被测设备和被测应用(APP
)。
二、Python
客户端如何使用Settings API
有2种方式来使用Settings
:1)建立会话时通过能力参数传入;2)会话执行过程中通过专门的接口进行修改。备注:本文所有测试代码的前提是已经安装Appium
和相关环境(例如JDK
、Android SDK
、AVD
模拟器),可以参考Appium
环境搭建。
2.1 建立会话时通过能力参数传入
键值对的方式为"appium:settings[<name>]"
:"<value>"
,其中<name>
是Settings
的名称,<value>
是待设置的值。以actionAcknowledgmentTimeout
参数为例,它表示等待一个动作执行确认的超时时间,例如模拟按钮的点击操作,操作完成后结果通知到客户端的超时时间。该参数的默认值是3
秒,示例如下:
import pytest
from appium import webdriver
from appium.options.android import UiAutomator2Options
from appium.webdriver.appium_service import AppiumService
# 开启服务端
APPIUM_HOST = '127.0.0.1'
APPIUM_PORT = 4723
@pytest.fixture(scope="session")
def start_appium_service():
server = AppiumService()
server.start(args=['--address', APPIUM_HOST, '-p', str(APPIUM_PORT)], timeout_ms=60000)
yield server
server.stop()
# 创建客户端到服务端的会话
def create_appium_session_by_api(custom_opts = None, appium_host = APPIUM_HOST, appium_port = APPIUM_PORT):
options = UiAutomator2Options()
if custom_opts is not None:
options.load_capabilities(custom_opts)
return webdriver.Remote(f'http://{appium_host}:{appium_port}', options=options)
def test_set_settings_in_capabilities(start_appium_service):
custom_opts = {
"appium:settings[actionAcknowledgmentTimeout]": 4321,
"appium:avd": "testPhone",
}
driver = create_appium_session_by_api(custom_opts)
settings = driver.get_settings()
assert settings["actionAcknowledgmentTimeout"] == 4321
2.2 会话执行过程中通过接口更改
执行过程中更改需要使用客户端webdriver
提供的接口,本文使用的是Python
,具体的修改接口是update_settings
,获取所有参数的接口是get_settings
,示例如下:
import pytest
from appium import webdriver
from appium.options.android import UiAutomator2Options
from appium.webdriver.appium_service import AppiumService
# 开启服务端
APPIUM_HOST = '127.0.0.1'
APPIUM_PORT = 4723
@pytest.fixture(scope="session")
def start_appium_service():
server = AppiumService()
server.start(args=['--address', APPIUM_HOST, '-p', str(APPIUM_PORT)], timeout_ms=60000)
yield server
server.stop()
# 创建客户端到服务端的会话
def create_appium_session_by_api(custom_opts = None, appium_host = APPIUM_HOST, appium_port = APPIUM_PORT):
options = UiAutomator2Options()
if custom_opts is not None:
options.load_capabilities(custom_opts)
return webdriver.Remote(f'http://{appium_host}:{appium_port}', options=options)
def test_set_settings(start_appium_service):
custom_opts = {
"appium:avd": "testPhone",
}
driver = create_appium_session_by_api(custom_opts)
settings = driver.get_settings()
assert settings["actionAcknowledgmentTimeout"] == 3000
modify_args = {
"actionAcknowledgmentTimeout": 4321,
}
driver.update_settings(modify_args)
settings = driver.get_settings()
assert settings["actionAcknowledgmentTimeout"] == 4321
三、Settings
参数详解
目前UiAutomator2
支持的Settings
参数具体描述如下,可以参考官方文档。
参数名称 | 参数类型 | 参数详解 |
---|---|---|
actionAcknowledgmentTimeout |
long |
等待动作完成并通知的超时时间,单位是毫秒。动作包括点击操作、文本设置操作、菜单按压操作等。以便Appium 框架能够判断动作是否已经成功。通常不建议修改该参数,默认值是3000 。 |
allowInvisibleElements |
boolean |
XML 源码树是否包含对用户不可见的元素(元素的displayed 属性是false )。该值默认是false 。 |
ignoreUnimportantViews |
boolean |
使能或禁止布局层次结构压缩。如果使能布局层次结构压缩,则布局层次结构从Acessibility 框架派生,只会包含对uiautomator 测试重要的节点。任何导致视图呈现或层次搜索效率降低的节点都会被移除。该值默认是false 。 |
elementResponseAttributes |
string |
包含在查找元素接口(findElement )响应中的元素属性名称,多个属性名称以分号分隔。默认只包含元素的UUID ,可以指定把如下属性项添加进来:name , text , rect , enabled , displayed , selected , attribute/<element_attribute_name> 。此外,要使用此参数功能,需要shouldUseCompactResponses 参数设置为false 。 |
enableMultiWindows |
boolean |
在构建XML 页面源码时是否包含用户可以交互的所有窗口(例如屏幕键盘)。默认值是false ,页面源码仅包含一个活动的应用程序窗口。 |
enableTopmostWindowFromActivePackage |
boolean |
在交互和页面源检索中,是否限制活动包中具有最高Z-order 的窗口。默认值是false ,并且活动应用程序窗口(可能不一定具有此顺序)包含在页面源中。 |
enableNotificationListener |
boolean |
是否启动toast 通知侦听器用于侦听新的toast 通知。默认此侦听器处于启用状态,并且UiAutomator2 server 会将toast 消息的文本包含到XML 页面源。 |
keyInjectionDelay |
long |
注入文本输入时,按键之间的延时时间。单位是毫秒,默认是0 。 |
scrollAcknowledgmentTimeout |
long |
滚动条滑动动作通知的超时时间,单位是毫秒,通常不建议修改该参数,默认值是200 。 |
shouldUseCompactResponses |
boolean |
与elementResponseAttributes 参数联合使用。如果shouldUseCompactResponses 设置为false ,那么查找元素接口的响应报文中,会包含elementResponseAttributes 参数指定的属性。默认值是true 。 |
waitForIdleTimeout |
long |
用于等待用户界面进入空闲状态的超时。默认情况下,除了UiDevice 之外的所有核心uiautomator 对象都将在开始搜索对象定位器(object's locator )指定的部件(widgest )之前执行此等待。一旦检测到空闲状态或超时(以先发生的为准),对象将开始等待选择器找到匹配项。如果在测试中遇到跟可访问性元素交互时时间延迟过长的情况,请考虑降低此设置的值。默认情况下为10000 ,单位是毫秒。 |
waitForSelectorTimeout |
long |
等待部件在用户界面变成可见(以便被选择器匹配)的超时时间。当使用选择器匹配目标时,因为用户界面的内容是动态的,有时目标不见不会立马在用户界面可见,因此无法被选择器检测到。本参数允许uiautomator 框架等待选择器去匹配,直到达到超时时间。单位是毫秒,默认是1000 。 |
normalizeTagNames |
boolean |
如果设置为true ,在页面源码XML 文档中,对于用于标记名的元素类型名称,执行unicode 到ascii 标准化。当应用程序中有包含Unicode 编码的类型名时,该选项是必要的。默认值是false 。 |
shutdownOnPowerDisconnect |
boolean |
被测设备与电源断开之后(例如只有电池供电时),是否要关闭被测设备上的UiAutomator2 server 。默认值是true 。 |
simpleBoundsCalculation |
boolean |
是否将元素边界计算为绝对值(参数值为true ),或检查元素是否被其他元素遮盖导致隐藏(参数值false )。参数设置为true 可以改善XML 页面源码生成的性能,但会降低边界的精度。所以慎用。 |
trackScrollEvents |
boolean |
是否使用滚动事件跟踪(true 时启用,默认值)。启用之后就可以用于计算contentSize 元素属性,另一方面,使能该参数会增加所有滚动动作的延迟。 |
wakeLockTimeout |
long |
UiAutomator2 server 持有唤醒锁的时间(获取唤醒锁,是为了防止被测设备在运行测试过程中进入睡眠)。默认情况下UiAutomator2 server 持有唤醒锁24 小时。该参数单位是毫秒,将该值设置为0,会强制UiAutomator2 server 释放唤醒锁。备注:唤醒锁(wake lock )是安卓的一种机制,防止设备在运行过程中进入睡眠状态。 |
serverPort |
int |
被测设备上启动UiAutomator2 server 的端口号,不要把这个值和appioum:systemPort 混淆了,appioum:systemPort 是Appium 服务端的UiAutomator2 driver 用于与UiAutomator2 server 通信使用的端口。本参数的设置范围是1024~65535 ,默认值是6790 。 |
mjpegServerPort |
int |
MJPEG 屏幕截图每秒钟最大的截图数量,默认值是10 ,范围是1~60 。 |
mjpegScalingFactor |
int |
MJPEG 屏幕截图对截图的缩放比例(百分比形式)。参数值范围是1~100 ,默认值是50 ,也就是默认情况下,会按照原图一半的比例生成截图。 |
mjpegServerScreenshotQuality |
int |
MJPEG 屏幕截图对截图有损压缩的比例(百分比形式)。参数值范围是1~100 ,默认值是50 ,也就是默认情况下,会按照原图质量的一半的比例进行压缩生成截图。 |
mjpegBilinearFiltering |
boolean |
MJPEG 屏幕截图对大小调整是否使用双线性滤波算法,默认值是false 。如果设置为true ,可以改善生成的缩放位图的质量,但是对性能有损耗。 |
useResourcesForOrientationDetection |
boolean |
定义UiAutomator2 server 用于检测被测设备方向的策略。默认情况下(false )使用被测设备的旋转值来达到此目的,因此对于某些设备该方法(旋转值)可能无法正常工作,可能导致纵向被检测为横向(或发过来)。在这种情况下,就需要设置本参数为true 。 |
enforceXPath1 |
boolean |
从UiAutomator2 server 的4.25.0 版本开始,XPath2 就是默认和推荐的元素定位解析器。如果某些场景下需要使用XPath1 。可以使能本参数。该参数只在通过XPATH 方式定位查找元素的时候生效,因此可以在测试脚本中使能该参数,XPATH 方式查找完元素后,关闭该参数。 |
limitXPathContextScope |
boolean |
由于历史原因,UiAutomator2 驱动限制了基于元素内容来搜索元素父元素的范围,这也就意味着findElement(By.xpath, "//root").findElement(By.xpath, "./..") 这种调用方式不会成功,因为驱动只会从目的XML 源码中收集root 的后继元素。limitXPathContextScope 参数设置为false 可以改变这种行为,变成搜索整个XML 页面源码。该参数默认是true 。 |
disableIdLocatorAutocompletion |
boolean |
根据安卓国际标准,元素的资源id 命名需要有形如<packageName>:id/ 的前缀以防止命名冲突。但是并非所有的应用都按照此标准执行,而UiAutomator2 驱动会检测传入的id 是否包含如上形式的前缀,没有的话会自动加上。因此对于某些未按照标准要求使用id 命名的应用会存在问题,可以使能本参数(设置为true ),关闭自动添加前缀功能。该参数默认值是false 。 |
includeExtrasInPageSource |
boolean |
XML 页面源码结果中是否包含extra 元素属性,包含的话,XPath 定位器就可以通过extra 来定位元素。如果extra 属性很大,使能该功能可能会影响性能。该参数默认是false 。 |
snapshotMaxDepth |
int |
源码树快照的最大深度,默认是70 ,该参数的范围是1~500 。如果该值较低,可能导致源码树上部分元素丢失;如果该值太高,可能导致堆栈溢出错误。需要UiAutomator2 驱动版本在2.27.0 及以上支持该参数。 |