Appium UIAutomator 在 API level = 17 (4.2) 上的问题

陈恒捷 · April 16, 2015 · Last by 扮猪吃老虎 replied at May 05, 2015 · 1410 hits
本帖已被设为精华帖!

最近由于某个 appium 的 bug,把 appium 从 1.2.0 升级到 1.3.4 ,结果跑不了了(找不到 Configurator 这个类)。查了一下相关资料,发现虽然 UIAutomator 在 API level 17 以后就有提供,但 API level 18 上做了一些调整,并且这些调整对测试有较大影响,所以在这里记录一下

目前已知的、可以感受到差异:

  1. 使用 uiautomatorviewer 查看元素时, API level 17 看不到 resource-id 这个属性(API 不支持), API 18 可以

  2. 使用 Appium 高于 1.3.4 的版本测试 4.2 时,可能会出现 java.lang.NoClassDefFoundError: com.android.uiautomator.core.Configurator 错误( 1.3.4 以后的貌似在出现这个错误前增加了对 API level 的检查,但我没测试过,不是很确定)。

代码级别的差异也很大:

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.2.2_r1/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java?av=f

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.3_r1/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java?av=f

打开后可以看到差异不少,API level 18 增加了不少文件,已有文件也做了不少变更。

官方目前对于 UIAutomator 的支持情况

官方文档中对 UIAutomator 的最低支持版本已经改为:Requires Android 4.3 (API level 18) or higher.

http://developer.android.com/tools/testing-support-library/index.html#UIAutomator

同时在官网 API level 17 时查看 UIAutomator API 会提示 API level 17 不支持 UIAutomator 。因此可以认为 4.2 的 UIAutomator 已经被废弃了。

appium 对 UIAutomator 的支持情况

appium 从 1.3.4 加入对 Configurator 这个类的依赖:

https://github.com/appium/appium/commit/af58dbe9f5306da46fc7ed7aeaca15304cf6496e

https://github.com/appium/appium/commit/5149d5113700fa622adc0d50eed6e82fd93f3276

https://github.com/appium/appium/commit/3104d03b9b169377fbcce26bd79a36ed70465cab

因此基本可以确定 1.3.4 以后的 appium 在 Android 上使用非 selendroid 模式都必须是在 API level > 18 上运行。相当于 Appium 1.3.4 及以后的版本都是在 4.3+ 后才能用 UIAutomator 。 1.3.4 以前的虽然可以在 API level 17 上运行,但一些 API level 18 才支持的功能 ( 如获取节点的 resource-id 属性) 肯定支持不了。

结论

对于 API level = 17 (4.2) 的 Android 设备,要不使用较低版本的 appium (如果你确定功能已经够用和够稳定),要不用 selendroid 模式运行。否则你会遇到错误且不改 appium 源码无法解决。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 14 条回复 时间 点赞

uiautomator做测试不稳定, 没有selendroid模式好. 大部分的case还是应该基于selendroid. 少部分跨app场景可以交给uiautomator

#1楼 @seveniruby 嗯。其实google自己的测试指南 也提倡 UIAutomator 用来做跨应用,Expresso做单应用。

#2楼 @chenhengjie123 从内部测试最稳定可靠. 是可依赖的. espresso也不错, 不过这个框架没太多亮点.

#3楼 @seveniruby “从内部测试”具体指什么?

#1楼 @seveniruby 看了instruments 从底层的设置,instrumentation 这个的地位就很高。

楼主,我用1.3.7,使用selendroid模式在4.2的机器上运行,查找元素时by xpath和by name 都失效了,有遇到过吗

#6楼 @sunrise 求 Log 。。。
你可以先试试用 log_source 把页面元素打印出来,然后看看里面是否确实有你需要的信息。
Selendroid 和 appium 不一样,它不是使用 uiautomator 的。

#7楼 @chenhengjie123

info: [debug] Proxied response received with status 200: {"value":"<?xml version=\"1.0\" encoding=\"UTF-8\"?><views><DecorView name=\"\" label=\"\" value=\"\" ref=\"a632f262-1a0f-86ae-6786-828e3425c61e\" id=\"\" shown=\"true\"><rect x=\"0\" y=\"0\" height=\"1280\" width=\"720\"/><FrameLayout name=\"\" label=\"\" value=\"\" ref=\"7315298b-fb33-a68d-f165-3f3c765b84f1\" id=\"windowBorder\" shown=\"true\"><rect x=\"0\" y=\"0\" height=\"1280\" width=\"720\"/><LinearLayout name=\"\" label=\"\" value=\"\" ref=\"57613bac-f8e0-815c-c0a9-346c2f412b91\" id=\"windowContentFrame\" shown=\"true\"><rect x=\"0\" y=\"0\" height=\"1280\" width=\"720\"/><ImageView name=\"\" label=\"\" value=\"\" ref=\"a036e6b6-869e-48dd-4792-8203e87faa0c\" id=\"windowIconic\" shown=\"false\"><rect x=\"0\" y=\"0\" height=\"0\" width=\"0\"/></ImageView><LinearLayout name=\"\" label=\"\" value=\"\" ref=\"98b1472f-c4b7-2dd0-e3e0-4c37aacef932\" id=\"\" shown=\"true\"><rect x=\"0\" y=\"0\" height=\"1280\" width=\"720\"/><LinearLayout name=\"\" label=\"\" value=\"\" ref=\"dd1fc08d-f9ed-ad49-f83b-d1bd33741666\" id=\"\" shown=\"true\"><rect x=\"0\" y=\"0\" height=\"1280\" width=\"720\"/><ViewStub name=\"\" label=\"\" value=\"\" ref=\"c2f52aae-f129-bd3b-6b79-40be3ff9eda3\" id=\"action_mode_bar_stub\" shown=\"false\"><rect x=\"0\" y=\"0\" height=\"0\" width=\"0\"/></ViewStub><FrameLayout name=\"\" label=\"\" value=\"\" ref=\"05ebe8d3-5e33-24b2-59a5-83920dc13fbf\" id=\"title_container\" shown=\"true\"><rect x=\"0\" y=\"50\" height=\"100\" width=\"720\"/><FrameLayout name=\"\" label=\"\" value=\"\" ref=\"efb8f90b-ca89-198a-781a-b2d983669ff7\" id=\"title_bar\" shown=\"true\"><rect x=\"0\" y=\"50\" height=\"100\" width=\"720\"/><FrameLayout name=\"\" label=\"\" value=\"\" ref=\"ec3c9c62-af1e-0084-3d6a-74754797dd9f\" id=\"title_bar_content_container\" shown=\"true\"><rect x=\"0\" y=\"60\" height=\"80\" width=\"690\"/><ShopListTabView name=\"\" label=\"\" value=\"\" ref=\"b36ede0e-4893-6359-d352-0eb435b22976\" id=\"\" shown=\"true\"><rect x=\"0\" y=\"60\" height=\"80\" width=\"690\"/><NovaLinearLayout name=\"\" label=\"\" value=\"\" ref=\"9e55bab1-cb0b-2a34-ce6a-b001377de200\" id=\"tab1\" shown=\"true\"><rect x=\"185\" y=\"70\" height=\"60\" width=\"160\"/><TextView name=\"\" label=\"\" value=\"全部\" ref=\"e08abc4c-18dd-5149-54e6-947274ead764\" id=\"title1\" shown=\"true\"><rect x=\"237\" y=\"81\" height=\"38\" width=\"56\"/></TextView></NovaLinearLayout><NovaLinearLayout name=\"\" label=\"\" value=\"\" ref=\"c8b119e3-e400-8b1f-a866-98b29856b322\" id=\"tab3\" shown=\"false\"><rect x=\"0\" y=\"60\" height=\"0\" width=\"0\"/><TextView name=\"\" label=\"\" value=\"\" ref=\"0e395fad-2f58-dc9a-9965-903bad2228a8\" id=\"title3\" shown=\"false\"><rect x=\"0\" y=\"60\" height=\"0\" width=\"0\"/></TextView></NovaLinearLayout><NovaLinearLayout name=\"\" label=\"\" value=\"\" ref=\"0b78e0a1-7804-4f95-f1cc-f32fcec24bdb\" id=\"tab2\" shown=\"true\"><rect x=\"345\" y=\"70\" height=\"60\" width=\"160\"/><TextView name=\"\" label=\"\" value=\"海外\" ref=\"4e813b8c-166f-d42c-5dc3-6d24354c037d\" id=\"title2\" shown=\"true\"><rect x=\"397\" y=\"81\" height=\"38\" width=\"56\"/></TextView></NovaLinearLayout></ShopListTabView></FrameLayout><LinearLayout name=\"\" label=\"\" value=\"\" ref=\"3968182f-98e7-9b07-58dc-0e713717bc07\" id=\"title_bar_left_view_container\" shown=\"true\"><rect x=\"0\" y=\"60\" height=\"80\" width=\"80\"/><CustomImageButton name=\"\" label=\"\" value=\"\" ref=\"006b6274-5957-5adc-49fd-c0598dd64e7b\" id=\"left_view\" shown=\"true\"><rect x=\"0\" y=\"60\" height=\"80\" width=\"80\"/></CustomImageButton></LinearLayout><LinearLayout name=\"\" label=\"\" value=\"\" ref=\"ea96617b-77b8-95b5-b1fe-c04f32332179\" id=\"title_bar_right_view_container\" shown=\"true\"><rect x=\"690\" y=\"60\" height=\"80\" width=\"0\"/></LinearLayout></FrameLayout></FrameLayout><FrameLayout name=\"\" label=\"\" value=\"\" ref=\"e2dbeb9f-21ab-2347-d4ed-e5222a3b4010\" id=\"content\" shown=\"true\"><rect x=\"0\" y=\"150\" height=\"1130\" width=\"720\"/><LinearLayout name=\"\" label=\"\"
value=\"\" ref=\"289328d0-4609-17c3-6ab2-c501d6626ef9\" id=\"\" shown=\"true\"><rect x=\"0\" y=\"150\" height=\"1130\" width=\"720\"/><LinearLayout name=\"\" label=\"\" value=\"\" ref=\"2051abac-200b-70b4-73e8-eddd3b42d894\" id=\"\" shown=\"true\"><rect x=\"0\" y=\"150\" height=\"101\" width=\"720\"/><ButtonSearchBar name=\"\" label=\"\" value=\"\" ref=\"6415e433-228d-814d-72f7-0929ff3b75c1\" id=\"button_search_bar\" shown=\"true\"><rect x=\"0\" y=\"150\" height=\"100\" width=\"720\"/><NovaLinearLayout name=\"\" label=\"\" value=\"\" ref=\"4ef6e1e9-e9e4-93c7-9976-ed6bce1bb71f\" id=\"search_layout\" shown=\"true\"><rect x=\"50\" y=\"179\" height=\"43\" width=\"622\"/><ImageView name=\"\" label=\"\" value=\"\" ref=\"9683c922-887a-e646-9ef6-e0a963d823e5\" id=\"search_icon\" shown=\"true\"><rect x=\"50\" y=\"185\" height=\"30\" width=\"52\"/></ImageView><TextView name=\"\" label=\"\" value=\"\" ref=\"6a008ef3-b983-4a17-b4e5-8e0450899079\" id=\"start_search\" shown=\"true\"><rect x=\"102\" y=\"179\" height=\"43\" width=\"570\"/></TextView></NovaLinearLayout></ButtonSearchBar><View name=\"\" label=\"\" value=\"\" ref=\"15eadf93-f95a-7dac-101b-4b8b01b81eb4\" id=\"\" shown=\"true\"><rect x=\"0\" y=\"250\" height=\"1\" width=\"720\"/></View></LinearLayout><RelativeLayout name=\"\" label=\"\" value=\"\" ref=\"f7ce828b-369d-5d17-acb9-b750d809e420\" id=\"\" shown=\"true\"><rect x=\"0\" y=\"251\" height=\"1029\" width=\"720\"/><NovaListView name=\"\" label=\"\" value=\"\" ref=\"3af43816-7cac-678e-3fab-e27a3d2cef9f\" id=\"list\" shown=\"true\"><rect x=\"0\" y=\"251\" height=\"1029\" width=\"720\"/><NovaTextView name=\"\" label=\"\" value=\"上海 GPS定位\" ref=\"3777db6d-6141-4e88-04fb-a416015e2d47\" id=\"text1\" shown=\"true\"><rect x=\"0\" y=\"251\" height=\"100\" width=\"720\"/></NovaTextView><CityGridLayout name=\"\" label=\"\" value=\"\" ref=\"1e557533-3d3d-135b-d712-4dfb0147f750\" id=\"\" shown=\"true\"><rect x=\"0\" y=\"350\" height=\"0\" width=\"720\"/><LinearLayout name=\"\" label=\"\" value=\"\" ref=\"5e2dc57d-40e6-a7cc-d41a-2316c1f7f9da\" id=\"\" shown=\"true\"><rect x=\"0\" y=\"350\" height=\"0\" width=\"720\"/><LinearLayout name=\"\" label=\"\" value=\"\" ref=\"5ab168d4-257b-8ec6-9969-e4b186293781\" id=\"layout\" shown=\"false\"><rect x=\"0\" y=\"350\" height=\"0\" width=\"0\"/><TextView name=\"\" label=\"\" value=\"常用\" ref=\"9e640494-f69b-823e-1aad-c8ddb15f6f2a\" id=\"city_title\" shown=\"false\"><rect x=\"0\" y=\"350\" height=\"0\" width=\"0\"/></TextView><LinearLayout name=\"\" label=\"\" value=\"\" ref=\"836bf452-585e-e90e-7d09-5f65c7b3fb55\" id=\"recommend_category_container\" shown=\"false\"><rect x=\"0\" y=\"350\" height=\"0\" width=\"0\"/></LinearLayout></LinearLayout></LinearLayout></CityGridLayout><CityGridLayout name=\"\" label=\"\" value=\"\" ref=\"517994ad-8106-f810-6155-c5392ed277ff\" id=\"\" shown=\"true\"><rect x=\"0\" y=\"349\" height=\"472\" width=\"720\"/><LinearLayout name=\"\" label=\"\" value=\"\" ref=\"4adeca2a-fc3c-0c04-3581-191be5ec6614\" id=\"\" shown=\"true\"><rect x=\"0\" y=\"349\" height=\"472\" width=\"720\"/><LinearLayout name=\"\" label=\"\" value=\"\" ref=\"2f2adc4b-f9e8-e6d3-04c5-0e4b9ed20cb3\" id=\"layout\" shown=\"true\"><rect x=\"0\" y=\"349\" height=\"472\" width=\"720\"/><TextView name=\"\" label=\"\" value=\"热门国内城市\" ref=\"72219a70-66f2-4e4a-f2f1-51206c995ecf\" id=\"city_title\" shown=\"true\"><rect x=\"0\" y=\"349\" height=\"92\" width=\"720\"/></TextView><LinearLayout name=\"\" label=\"\" value=\"\" ref=\"6f611b63-af9d-c145-4b58-b4128e398203\" id=\"recommend_category_container\" shown=\"true\"><rect x=\"0\" y=\"441\" height=\"380\" width=\"720\"/><LinearLayout name=\"\" label=\"\" value=\"\" ref=\"b5185893-d3fb-b5c0-e11d-93f33a60b0ec\" id=\"\" shown=\"true\"><rect x=\"20\" y=\"441\" height=\"95\" width=\"680\"/><NovaTextView name=\"\" label=\"\" value=\"上海\" ref=\"955548ea-700b-da28-b2c6-d4b0be78f1dd\" id=\"\" shown=\"true\"><rect x=\"28\" y=\"449\" height=\"79\" width=\"210\"/></NovaTextView><NovaTextView name=\"\" label=\"\" value=\"北京\" ref=\"93ae96
48-ced9-1f25-e7d1-a9aa6c3f6d63\" id=\"\" shown=\"true\"><rect x=\"254\" y=\"449\" height=\"79\" width=\"211\"/></NovaTextView><NovaTextView name=\"\" label=\"\" value=\"广州\" ref=\"d386e692-d282-b396-e4d9-7ec52cef6fed\" id=\"\" shown=\"true\"><rect x=\"481\" y=\"449\" height=\"79\" width=\"211\"/></NovaTextView></LinearLayout><LinearLayout name=\"\" label=\"\" value=\"\" ref=\"ccec1c0f-4db7-c78b-b904-d2a7e4095e02\" id=\"\" shown=\"true\"><rect x=\"20\" y=\"536\" height=\"95\" width=\"680\"/><NovaTextView name=\"\" label=\"\" value=\"深圳\" ref=\"9ae81fa4-44fd-b96c-1f87-0159b2657526\" id=\"\" shown=\"true\"><rect x=\"28\" y=\"544\" height=\"79\" width=\"210\"/></NovaTextView><NovaTextView name=\"\" label=\"\" value=\"成都\" ref=\"7ca2aa20-645b-aa36-ebf8-41d42446f85c\" id=\"\" shown=\"true\"><rect x=\"254\" y=\"544\" height=\"79\" width=\"211\"/></NovaTextView><NovaTextView name=\"\" label=\"\" value=\"重庆\" ref=\"7607df9c-df90-be2b-c023-95b6db60e671\" id=\"\" shown=\"true\"><rect x=\"481\" y=\"544\" height=\"79\" width=\"211\"/></NovaTextView></LinearLayout><LinearLayout name=\"\" label=\"\" value=\"\" ref=\"aeb87f2d-d35e-7d8f-a305-05b18d17aae7\" id=\"\" shown=\"true\"><rect x=\"20\" y=\"631\" height=\"95\" width=\"680\"/><NovaTextView name=\"\" label=\"\" value=\"天津\" ref=\"f9a4686e-e5bc-6334-bc39-861f60098628\" id=\"\" shown=\"true\"><rect x=\"28\" y=\"639\" height=\"79\" width=\"210\"/></NovaTextView><NovaTextView name=\"\" label=\"\" value=\"杭州\" ref=\"e0820233-c1b8-2807-8e50-30045ff35031\" id=\"\" shown=\"true\"><rect x=\"254\" y=\"639\" height=\"79\" width=\"211\"/></NovaTextView><NovaTextView name=\"\" label=\"\" value=\"南京\" ref=\"205a527d-c561-bc79-8b58-052020a352bb\" id=\"\" shown=\"true\"><rect x=\"481\" y=\"639\" height=\"79\" width=\"211\"/></NovaTextView></LinearLayout><LinearLayout name=\"\" label=\"\" value=\"\" ref=\"19bf87fb-4096-d06d-5f83-5901d7bd40d0\" id=\"\" shown=\"t
info: <-- GET /wd/hub/session/759cae02-f87e-d839-00a2-823886eaf632/source 200 468.826 ms - 14837
info: --> POST /wd/hub/session/759cae02-f87e-d839-00a2-823886eaf632/element {"
using":"name","sessionId":"759cae02-f87e-d839-00a2-823886eaf632","value":"北京"}
info: [debug] Proxying command to localhost:8080
info: [debug] Making http request with opts: {"
url":"http://localhost:8080/wd/hub/session/759cae02-f87e-d839-00a2-823886eaf632/element","method":"POST","json":{"using":"name","sessionId":"759cae02-f87e-d839-00a2-823886eaf632","value":"北京"}}

info: [debug] Responding to client with error: {"status":7,"value":{"message":"An element could not be located on the page using the given search parameters.","origValue":"Element was not found."},"sessionId":"759cae02-f87e-d839-00a2-823886eaf632"}

info: <-- POST /wd/hub/session/759cae02-f87e-d839-00a2-823886eaf632/element 500 5099.663 ms - 201

info: --> GET /wd/hub/status {}

info: [debug] Proxying command to localhost:8080
info: [debug] Making http request with opts: {"url":"http://localhost:8080/wd/hub/status","method":"GET"}

info: [debug] Proxied response received with status 200: {"value":{"supportedApps":[],"build":{"browserName":"selendroid","version":"0.13.0"},"os":{"arch":"armeabi-v7a","version":"17","name":"Android"},"supportedDevices":[]},"status":0}

#7楼 @chenhengjie123

def test_ActionButton(self): #首页8个按钮,3
for i in range(100):
activity = self.driver.current_activity
if activity == "com.dianping.main.city.CityListSwitchActivity" :
time.sleep(2)
break
else:
time.sleep(2)
print self.driver.page_source
el = self.driver.find_element_by_name("北京")
el.click()

#7楼 @chenhengjie123 如上,我打印出来是有这个元素的,by name却找不到,xpath也不行。

陈恒捷 #11 · May 06, 2015 作者

#10楼 @sunrise find_element_by_name 不是匹配 value 的。你的 "北京" 是 value 的值。
参考:http://selendroid.io/native.html#name
而且你的 Log 里面的 xml 有点怪,有些节点名称我也没见过,如 NovaTextView,不知道是不是自定义控件。
不过用 xpath 应该能找到啊。你的 xpath 怎么写的?

#11楼 @chenhengjie123 谢谢你的指正,by_link_text可以找到。Xpath我是直接复制Appium Inspector的。我先研究下selendroid的文档,多谢。

#11楼 @chenhengjie123 很奇怪,selendroid模式下所有的ListView和TextView都变成了NovaListView和NovaTextView,我把Xpath修改一下就可以了。

陈恒捷 #14 · May 06, 2015 作者

#13楼 @sunrise selendroid 是基于 Instrumentation 的,所以获取到的元素列表会和 Appium 有所不同是正常的。

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up