对手机软件自动化就是写程序模拟人的行为操控手机 app,我们操控 app 具体是指操控 app 上的控件(文本框,按钮等等)。如果想操控这些控件,首先就要找到它们。
我们可以通过控件的属性找到这些控件,通过 Android SDK 下的 uiautomatorviewer.bat 工具可以查看控件的属性。该工具位于 Android SDK 的 /tools/bin/ 目录下。
为了更真实实用,我们采用真机做试验。当然如果你想使用模拟器,没关系,方法都是一样的,你完全可以按照下面的方法去实践。
打开 uiautomatorviewer.bat 工具,点击左上角两个带安卓图标的按钮中任一个。
注意:如果目标设备的 API Level 低于 18 则 UIAutomatorViewer 不完全能获得对应的控件的属性,只有等于大于 18 的时候才能使用,所以,最好确保你的设备的安卓系统版本大于 18。
通过 uiautomatorviewer.bat 工具可以查看对象的 id 属性,resource-id 就是我们理解的 id 属性了。
例子:
driver.find_element_by_id("com.sec.android.app.popupcalculator:id/bt_05")
通过 uiautomatorviewer.bat 工具可以查看对象的 name 属性,首先会先查找 content-desc 的值作为 name 值,如果 content-desc 的值为空,则继续查找 text 的值作为 name 值。
例子:
''' 因为 find_element... 找到的是第一个 name 属性符合条件的控件,返回控件。 因为符合 name 为 5 条件的控件就一个,所以下面代码定位 ok。 ''' driver.find_element_by_name("5") ''' 因为 find_elements... 找到的是所有 name 属性符合条件的控件,返回一个数组。 因为符合 name 为 5 条件的控件就一个,我们取数组的第一个即可。 ''' driver.find_elements_by_name("5")[0]
通过 uiautomatorviewer.bat 工具可以查看对象的 class 属性,class 就是我们要查找的 class 了。
计算器界面上的的 class 属性是:android.widget.ImageButton
。
例子:
''' 因为 find_element... 找到的是第一个 class 属性符合条件的控件,返回控件。 因为第一个 class 符合条件的控件清除控件,则返回的是清除控件。 ''' driver.find_element_by_class_name("android.widget.ImageButton") ''' 因为 find_elements... 找到的是所有 class 属性符合条件的控件,返回数组。 因为控件 5 是第九个控件,所以去数组的下标 9。 ''' driver.find_elements_by_class_name("android.widget.ImageButton")[9]
在 WebDriver 上 XPath 定位是功能强大的一种定位方式。我个人惯用于此方法来定位 Web 页面上的元素。下面看看在 Android 上 XPath 定位的用法。
用 class 的属性来替代做标签的名字。
例子:
driver.find_element_by_xpath("//android.view.ViewGroup/android.widget.ImageButton") # 找到第一个符合条件的控件 driver.find_elements_by_xpath("//android.view.ViewGroup/android.widget.ImageButton") # 找到所有符合条件的控件
当果如果出现 class 相同的情况下可以用控件的属性值进行区分。
driver.find_element_by_xpath("//android.widget.ImageButton[contains(@text,'7')]").click(); # 7 driver.find_element_by_xpath("//android.widget.ImageButton[contains(@content-desc,'times')]")).click(); # * driver.find_element_by_xpath("//android.widget.ImageButton[contains(@text,'5')]").click(); # 5 driver.find_element_by_xpath("//android.widget.ImageButton[contains(@content-desc,'equals')]").click(); # =
XPath 在 Appium 上的用法依然很强大,有时需要写更臭更长的定位语法,因为 APP 上元素的 class 命令本来就长,再加上多层级,结果可想而知。
这个方法属于 Appium 扩展的定位方法。
其实,我们的核心是要找到元素的 contentDescription 属性。它就是元素的 content-desc 。
例子:
driver.find_element_by_accessibility_id("5").click();
这个方法也属于 Appium(Android)扩展的定位方法。同样使用 UIAutomatorViewer.bat 工具直接查看。
也就是说一个元素的任意属性都可以通过android uiautomator方法来进行定位,但要保证这种定位方式的唯一性。
例子:
driver.find_element_by_android_uiautomator("new UiSelector().text(\"clr\")").click(); driver.find_element_by_android_uiautomator("new UiSelector().text(\"8\")").click(); driver.find_element_by_android_uiautomator("new UiSelector().description(\"plus\")").click(); driver.find_element_by_android_uiautomator("new UiSelector().text(\"5\")").click(); driver.find_element_by_android_uiautomator("new UiSelector().description(\"equals\")").click();
需要注意的是 description() 方法用的是 content-desc 属性。
清晰,易懂,博主的教程就是我等屌丝的福音
终于知道 text 和 content-desc 是什么意思了
感觉好牛逼
大神果然是大神,我的安卓系统是8.0的。 延时也猜想是网络请求导致的。你刚好是在研究自定义appium,能不能帮助解决一下。
大神你也可以提出UiAutomator2中TouchAction遇到的问题。
我还有一个想法,一台安卓设备可以被两个driver控制,一个driver用UiAutomator2查找定位元素,一个driver用UiAutomator1来执行TouchAction动作!
期待解答!
用真机讲解,博主真用心