目录
上一篇我们利用appium完成了元素定位,除了appium外用UiAutomator也可以实现元素定位。不过UiAutomator只能用于Android系统,无法兼容IOS。find_element_by_android_uiautomator
同样由于新版本不支持find_element_by_android_uiautomator,我们用find_element(By.ANDROID_UIAUTOMATOR,value)和find_elements(By.ANDROID_UIAUTOMATOR,value)来实现元素定位。我们分别对常用的属性值进行说明。
1、利用text属性进行定位
text属性如果可以唯一定位到元素的话使用起来非常方便,测试人员可以非常简单地识别出text属性的值,如果做封装都可以不用元素定位工具直接输入text值就行了。用text属性要注意,如果有空格容易把空格落下,千万要将空格一块复制过来。
对于text属性可以用如下几个方法
text:输入的值就是text中的值
textContains:元素text值包含输入的值
textStartsWith:元素的text值以输入的值开头
textMatches:正则表达式匹配,输入的值匹配text值
如下图,我们用uiautomatorviewer进行定位,记一笔按钮的text值是“记一笔”
我们通过text属性值来实现元素定位,代码实现定位到该元素,并打印出text值
'''
通过UIAUTOMATOR的text属性定位到元素,并打印文本
'''
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
import time
# For W3C actions
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.actions import interaction
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.pointer_input import PointerInput
caps = {}
caps["platformName"] = "Android"
caps["appium:platfformVersion"] = "11"
caps["appium:deviceName"] = "OFYDHUCIPN8PHEBI"
caps["appium:appPackage"] = "com.mymoney"
caps["appium:appActivity"] = "com.mymoney.biz.main.v12.MainActivityV12"
caps["appium:noReset"] = True
caps["appium:noSign"] = True
caps["appium:unicodeKeyboard"] = True
caps["appium:resetKeyboard"] = True
caps["appium:ensureWebviewsHavePages"] = True
caps["appium:nativeWebScreenshot"] = True
caps["appium:newCommandTimeout"] = 3600
caps["appium:connectHardwareKeyboard"] = True
driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", caps)
#以上代码从Session Information复制,直接使用
#通过text属性实现元素定位
#text属性全匹配
add_trans_btn_1 = driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,('text("记一笔")'))
#打印所有定位到元素的文本
print ("通过text属性定位到元素的文本为:",add_trans_btn_1.text)
#通过textContains实现元素定位
add_trans_btn_2 = driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,('textContains("一笔")'))
#打印所有定位到元素的文本
print ("通过textContains定位到元素的文本为:",add_trans_btn_2.text)
#通过textStartsWith实现元素定位
add_trans_btn_3 = driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,('textStartsWith("记一")'))
#打印所有定位到元素的文本
print ("通过textStartsWith定位元素的文本为:",add_trans_btn_3.text)
#通过textMatches实现元素定位
add_trans_btn_4 = driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,('textMatches("记.+笔")'))
#打印所有定位到元素的文本
print ("通过textMatches定位元素的文本为:",add_trans_btn_4.text)
#退出
driver.quit()
运行结果为
[Running] python -u "d:\Test\Android_Test\find_element_test.py"
通过text属性定位到元素的文本为: 记一笔
通过textContains定位到元素的文本为: 最近一笔 保健费 1,597.00
通过textStartsWith定位元素的文本为: 记一笔
通过textMatches定位元素的文本为: 记一笔
[Done] exited with code=0 in 34.827 seconds
我们可以看到通过textContains定位包含“一笔”到了另外的元素,如下这个
2、利用resource-id属性进行定位
resourceId:输入的值为resource-id
reresourceIdMatches:输入的值通过正则表达式匹配resource-id(个人认为元素定位还写正则比表达式太过于繁琐,能用值定位的就用值定位,定位不到的就用几个属性值组合定位好了)
如下图,resource-id对应的为resource-id
代码段为
#通过resourceId实现元素定位
add_trans_btn_5 = driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,('resourceId("com.mymoney:id/add_trans_btn")'))
#打印定位到元素的文本
print("通过resourceId定位元素的文本为:",add_trans_btn_5.text)
#退出
driver.quit()
运行结果
[Running] python -u "d:\Test\Android_Test\find_element_test.py"
通过resourceId定位元素的文本为: 记一笔
[Done] exited with code=0 in 15.207 seconds
3、利用className属性进行定位
className对应的为class属性,用法为driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,('className("android.widget.Button")'))
代码示意:
#通过className来定位元素,class一般会有多个元素,我们用find_elements
add_trans_btns = driver.find_elements(AppiumBy.ANDROID_UIAUTOMATOR,('className("android.widget.Button")'))
for add_trans_btn in add_trans_btns:
print("class 为 add_trans_btn 的元素文本:",add_trans_btn.text)
driver.quit()
运行结果为
[Running] python -u "d:\Test\Android_Test\find_element_test.py"
class 为 add_trans_btn 的元素文本: 预算
class 为 add_trans_btn 的元素文本: 图表
class 为 add_trans_btn 的元素文本: 模板
class 为 add_trans_btn 的元素文本: 社区
class 为 add_trans_btn 的元素文本: 服务
class 为 add_trans_btn 的元素文本: 账户
class 为 add_trans_btn 的元素文本: 流水
class 为 add_trans_btn 的元素文本: 记一笔
class 为 add_trans_btn 的元素文本: 项目
class 为 add_trans_btn 的元素文本: 设置
[Done] exited with code=0 in 15.971 seconds
4、多个元素属性结合使用
用uiautomator进行元素定位有一个优势,在第一个元素属性后面再加一个就行,例如我们用className和Text结合起来定位记一笔这个按钮,可以用如下代码
#多个元素属性结合使用,利用className和text结合使用
add_trans_btn = driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,('className("android.widget.Button").text("记一笔")'))
print("多个元素属性结合使用定位到的元素的文本:",add_trans_btn.text)
driver.quit()
运行结果如下,可以快速定位到元素
[Running] python -u "d:\Test\Android_Test\find_element_test.py"
多个元素属性结合使用定位到的元素的文本: 记一笔
[Done] exited with code=0 in 13.702 seconds
5、description属性:
可以用description\descriptionContains\descriptionMatches\descriptionStartsWith,对应的属性为context-desc,我们可以看到这个元素属性的值为空,无法进行元素定位
6、fromParent:兄弟定位
通过兄弟节点定位,当该元素无法唯一定位时,可以通过此方式连准确定位,如下我们想定位记一笔这个元素的兄弟元素账户,记一笔按钮的resource-id是com.mymoney:id/add_trans_btn,而流水按钮元素的resource-id是“com.mymoney:id/nav_btn_second”
代码如下
#通过兄弟节点定位,当该元素无法唯一定位时,可以通过此方式连准确定位
brother0 = driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,('resourceId("com.mymoney:id/add_trans_btn").fromParent(resourceId("com.mymoney:id/nav_btn_second"))'))
print("通过兄弟节点定位到的元素的文本:",brother0.text)
driver.quit()
运行结果
[Running] python -u "d:\Test\Android_Test\find_element_test.py"
通过兄弟节点定位到的元素的文本: 流水
[Done] exited with code=0 in 15.332 seconds
7.childSelector:父子定位
父子定位,用父节点和子节点元素属性结合定位某个元素。如下图父节点的resource-id是com.mymoney:id/bottom_content_container_ly,子节点的用text属性来定位
代码示例如下
#通过父子节点定位,当该元素无法唯一定位时,可以通过此方式连准确定位
child_elemnts = driver.find_elements(AppiumBy.ANDROID_UIAUTOMATOR, 'resourceId("com.mymoney:id/bottom_content_container_ly").childSelector(text("记一笔"))')
#答应所有满足条件的元素的文本
for child in child_elemnts:
print ("通过父子节点定位到的元素的文本:",child.text)
driver.quit()
运行结果
[Running] python -u "d:\Test\Android_Test\find_element_test.py"
通过父子节点定位到的元素的文本: 记一笔
[Done] exited with code=0 in 14.175 seconds
8、index:序列【其父元素的第几个节点】
如下图,记一笔按钮是父元素的第2个元素,我们用index来定位它,需要注意index后面带的属性是该元素自己的属性不是其父节点的。我就是第一次用的时候后面属性用的是父节点的,导致一直失败
.
代码示例:
#通过index来定位元素,定位元素的第3个元素为我们要定位的记一笔按钮
index = driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, 'index(2).resourceId("com.mymoney:id/add_trans_btn")')
print ("通过index定位到的元素的文本:",index.text)
driver.quit()
运行结果:
[Running] python -u "d:\Test\Android_Test\find_element_test.py"
通过index定位到的元素的文本: 记一笔
[Done] exited with code=0 in 15.399 seconds
9 instance:实例【所有结果 里面的第几个元素】
当某个元素属性定位到多个元素时,可以用此方法快速定位到我们想要的元素
示例代码
#通过className来定位元素,class一般会有多个元素,我们用find_elements
add_trans_btns = driver.find_elements(AppiumBy.ANDROID_UIAUTOMATOR,('className("android.widget.Button")'))
for add_trans_btn in add_trans_btns:
print("class 为 add_trans_btn 的元素文本:",add_trans_btn.text)
#通过class定位的元素第7个为记一笔,我们用instance(7)来定位它
instance7 = driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,'instance(7).className("android.widget.Button")')
print("通过instance定位到元素的文本是,",instance7.text)
运行结果
[Running] python -u "d:\Test\Android_Test\find_element_test.py"
class 为 add_trans_btn 的元素文本: 预算
class 为 add_trans_btn 的元素文本: 图表
class 为 add_trans_btn 的元素文本: 模板
class 为 add_trans_btn 的元素文本: 社区
class 为 add_trans_btn 的元素文本: 服务
class 为 add_trans_btn 的元素文本: 账户
class 为 add_trans_btn 的元素文本: 流水
class 为 add_trans_btn 的元素文本: 记一笔
class 为 add_trans_btn 的元素文本: 项目
class 为 add_trans_btn 的元素文本: 设置
通过instance定位到元素的文本是, 记一笔
[Done] exited with code=0 in 18.524 seconds