AppiumDriver 的各种 findElement
方法的尝试,尝试的目标应用是 SDK 自带的 Notepad 应用。
示例
el = driver.findElementByName("Add note");
assertThat(el.getText(),equalTo("Add note"));
如何获得 Name
安卓设备没有找到适合的方法,尝试用 Appium Inspector,但是使用了当前最新的 “AppiumForWindows-1.2.3.1” 没有看到这个属性,且 Inspector 在 Windows 下面非常的不稳定,很容易 crash。真心期望 Appium 团队尽快解决这个问题。iOS 设备倒可以用 Appium Inspector 获得。
建议
个人建议可以尝试先用 view 显示的文本作为 name 看是否能拿到该控件,按照我个人的经验一般都是会成功的,所以我很怀疑安卓上面控件的 name 是否就等于 text。如果确实还是不行的话就只好放弃用 name 了。或者等待 Appium 后来的稳定的 inspector 发布后看是否可以获得控件的 name。
这个方法在 Appium1.0 之后其实已经过时而要被 findElementByAccessibilityId 取代得了,不知道为什么还能调用,猜想是 Appium 团队想保留一定的兼容性以平滑过度吧。请查看:https://github.com/appium/appium/blob/master/docs/en/advanced-concepts/migrating-to-1-0.md
示例
el = driver.findElementByAndroidUIAutomator("new UiSelector().text(\"Add note\")");
assertThat(el.getText(),equalTo("Add note"));
如何获得 UIAutomator 参数
UIAutomator 获取控件的方式多种多样,都是通过 UiSelector 对象来去查找,比如使用 view 的 text 文本去当前窗口查找控件,这里不做累述,往后会另起一篇文章来描述 UIAUtomator 获取控件的方式,到时直接套用进来就可以了。
示例
el = driver.findElementByClassName("android.widget.TextView");
assertThat(el.getText(),equalTo("Add note"));
如何获得控件的 ClassName
可以使用 UIAutomatorViewer 工具直接查看
建议
使用 ClassName 一般获得的 view 都不止一个,所以应该需要遍历一遍得到的 views,然后缩写搜索条件来获得目标控件。示例中因为只有一个 textview 控件在窗口上面,所以不需要遍历。
示例
el = driver.findElementById("android:id/title");
assertThat(el.getText(),equalTo("Add note"));
如何获得 Resource Id
可以通过 UIAutomatorViewer 获得
建议
如果目标设备的 API Level 低于 18 则 UIAutomatorViewer 不能获得对应的 Resource ID,只有等于大于 18 的时候才能使用。
示例
el = driver.findElementByAccessibilityId("menu_add_note_description");
assertThat(el.getText(),equalTo("node"));
如何获得 AccessibilityId
可以通过 UIAutomatorViewer 或者 Appium Inspector 获得。
注释
Accessibility ID 在 Android 上面就等同于 contentDescription。这个属性是方便一些生理功能有缺陷的人使用应用程序的。比如我们有一个 ImageView 里面放置一张颜色复杂的图片,可能一些色弱色盲的人,分不清这张图片中画的是什么东西。如果用户安装了辅助浏览工具比如 TalkBack,TalkBack 就会大声朗读出用户目前正在浏览的内容。TextView 控件 TalkBack 可以直接读出里面的内容,但是 ImageView,TalkBack 就只能去读 contentDescription 的值,告诉用户这个图片到底是什么。
鉴于这是一个隐藏属性,而 Android 上用于查找控件的各种属性可能有所缺失或者有重复(比如 id 重复,比如一个 list 下面的所有项可能都是叫做 “id/text1”),所以最佳的办法就是跟开发团队沟通好每个 view 都赋予一个唯一的 contentDescription。
这个方法 Appium1.0 以后已经过时并被以上的 findElementByClassName 取代了,请查看https://github.com/appium/appium/blob/master/docs/en/advanced-concepts/migrating-to-1-0.md
示例
java
el = driver.findElementByXPath("//android.widget.TextView[contains(@text,'Add note')]");
//el = driver.findElement(By.xpath("//android.widget.TextView"));
assertThat(el.getText(),equalTo("Add note"));
XPath 格式变化
从老版本的 Appium0.18.x 升级到现在的 Appium1.x 后,注意 class name 和 xpath 策略的变化:你现在需要使用 FQCN 来描述你的控件。也就是说原来的:findElementByXpath(""//TextView[contains(@text,'Add note')]"")
需要改成findElementByXpath("//android.widget.TextView[contains(@text,'Add note')]")
详细变动请查看《Appium0.18.x 迁移到 Appium1.x 须知事项》
参考
据说不是很稳定:https://github.com/appium/appium/issues/3371
sometimes uiautomator fails to create the dump.xml. A client side retry may help. I don't think there's much we can do about the problem until Google fixes uiautomator.
作者:天地会珠海分舵
http://techgogogo.com
http://blog.csdn.net/zhubaitian