前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >appium中ios元素定位

appium中ios元素定位

作者头像
赵云龙龙
发布2021-04-23 11:15:22
3.1K0
发布2021-04-23 11:15:22
举报
文章被收录于专栏:python爱好部落python爱好部落

appium中,IOS和Android元素定位方法有些不同。 查找元素的顺序,个人认为速度从快到慢的顺序是这样的: ios_predicate >> accessibility_id >> class_name >>xpath 可以写个demo来测试一下。

1,accessibility_id

替代以前的name定位方式,在 iOS 上,主要使用元素的label或name(两个属性的值都一样)属性进行定位,如该属性为空,也是不能使用该属性。

代码语言:javascript
复制
driver.find_element_by_accessibility_id(‘ClearEmail’)
2、class_name

使用元素的type属性定位,特别注意该属性的唯一性!class_name唯一的情况并不多,一般情况下用不上。

代码语言:javascript
复制
driver.find_element_by_class_name(‘XCUIElementTypeButton’)
3、xpath

由于 iOS 10开始使用的 XCUITest 框架原生不支持,定位速度很慢,所以官方现在不推荐大家使用,也有其他替代的定位方式可使用。 1)使用绝对路径定位:

代码语言:javascript
复制
driver.find_element_by_xpath(’/XCUIElementTypeApplication/XCUIElementTypeButton’)

2)使用相对路径定位

代码语言:javascript
复制
driver.find_element_by_xpath(’//XCUIElementTypeButton’)

3)通过元素的索引定位

代码语言:javascript
复制
driver.find_element_by_xpath(’//XCUIElementTypeButton[index]’)

4).通过元素的属性定位 一种属性:

代码语言:javascript
复制
driver.find_element_by_xpath(”//className[@value=‘ClearEmail’]")

两种属性:

代码语言:javascript
复制
driver.find_element_by_xpath("//className[@value=‘ClearEmail’][@ visible =true]")

部分属性(最强大):

代码语言:javascript
复制
driver.find_element_by_xpath("//className[contains(@value,‘ClearEmail’)]")
4、ios_predicate

在 iOS 的 UI 自动化中,使用原生支持的Predicate定位方式是最好,可支持元素的单个属性和多个属性定位,强烈推荐使用。 使用方法,举例如下:

代码语言:javascript
复制
driver.find_element_by_ios_predicate("value == 'ClearEmail'")
driver.find_element_by_ios_predicate("type == 'XCUIElementTypeButton' AND value == 'ClearEmail'")

1)比较运算符:>、<、==、>=、<=、!= 可用于数值和字符串的比较: 如:value>100 或value == 'ClearEmail' 或 value != 'ClearEmail'

代码语言:javascript
复制
driver.find_element_by_ios_predicate("value>100")

2)范围运算符:IN、BETWEEN 可用于数值和字符串的范围核对 如:value BETWEEN {1,6} 或 value IN {'Clear','Email'}

代码语言:javascript
复制
driver.find_element_by_ios_predicate("value BETWEEN {1,6}")

3)字符串相关:CONTAINS、BEGINSWITH、ENDSWITH 包含某个字符串,如:value CONTAINS 'Email' 以某个字符串开头,如:value BEGINSWITH 'Clear' 以某个字符串结束,如:value ENDSWITH '班级Email'

代码语言:javascript
复制
driver.find_element_by_ios_predicate("value CONTAINS 'Email'")

4)通配符:LIKE 其中:?代表一个字符,代表多个字符 如:一个元素的value属性为ClearEmail: value LIKE 'Clear?mail' value LIKE 'Clear' 以上这么多种文本都可以被识别为同一个元素。

代码语言:javascript
复制
driver.find_element_by_ios_predicate("value LIKE 'Clear*'")

5)正则表达式:MATCHES 如:一个元素的value属性为ClearEmail:

代码语言:javascript
复制
value MATCHES '^C.+l$'
driver.find_element_by_ios_predicate("value MATCHES '^C.+l$'")

6)两种及两种以上属性定位元素:AND 单个属性定位用符号AND连接起来即可,如下:

代码语言:javascript
复制
driver.find_element_by_ios_predicate("type == 'XCUIElementTypeButton' AND value == 'ClearEmail'")

其中属性名参照inspector的属性字段,关键字LIKE,MATCHES,CONTAINS,BEGINSWITH,ENDSWITH必须是大写,匹配的字符需要用单引号

官方参考地址:

https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/ios_predicate.md

最后给个建议:

1 选择定位方式的判断:

如果显示在界面的文本唯一或是第一个出现:使用accessibility

如果class唯一或是第一个出现:className

ID或class不方便定位,控件属性有明确的匹配规则:iOSNsPredicate

如果有工具可以直接给出准确的xpath:xpath

实在不行就用坐标吧 driver.tap([(30, 95), [30, 98]], 500)

2 如果控件的属性visible是false的话,请使用控件坐标并获取中心点用tap点击,直接点击控件会失败

自动处理系统权限弹框

autoAcceptAlerts:True 低版本有效 autoAcceptAlerts 如果它们弹出,将自动接受所有iOS警报。这包括隐私访问权限警报(例如,位置,联系人,照片)。默认为false。true 要么 false autoDismissAlerts 如果所有iOS警报弹出,将自动将其关闭。这包括隐私访问权限警报(例如,位置,联系人,照片)。默认为false。true 要么 false

代码语言:javascript
复制

def get_desired_capabilities():
   desired_caps = {
       #平台名称
       'platformName': 'iOS',
       #平台版本
       'platformVersion': '11.3',
       #设备名称
       'deviceName': 'iPhone 8 Plus',
       #app 的地址
       'app': '/Users/tanzhiwu/Desktop/appium自动化测试/UTengineFrameworkTest.app',
       #bundleid 如果没有填 app 地址,填了这个 id 就会直接运行已安装的 app
       'bundleId': 'com.ut.pc.UTengineFrameworkTest',
       #超时时间
       'newCommandTimeout': 60,
       #自动化测试平台
       'automationName': 'Appium',
       #是否不重新安装启动
       'noReset': True
       #自动处理系统权限弹框
       #`autoAcceptAlerts`:True 低版本有效
   }
   return desired_caps


#def setUp(self):
       #获取我们设定的 capabilities,通知 appium Server 创建相应的对话
       #desired_caps = desired_capabilities.get_desired_capabilities()
       #获取 Server 的地址
       #uri          = desired_capabilities.get_uri()
       #创建会话,得到 driver 对象,driver 对象封装了所有的设备操作
       #self.driver = webdriver.Remote(uri,desired_caps)
       #设定等待时间,系统函数,在这个时间内会持续获取,超时会失败
       #self.driver.implicitly_wait(10)
       #处理系统权限弹框(新版本方法)
       #self.driver.switch_to.alter.accept()
import time, os
from appium import webdriver
from appium.webdriver.common.touch_action import TouchAction

driver = webdriver.Remote(command_executor='http://127.0.0.1:4723/wd/hub',
                         desired_capabilities={
                             'bundleId': 'chuxin.shimo.wendang.2014',
                             'platformName': 'iOS',
                             'platformVersion': '11.2.5',
                             'deviceName': 'iPhone7 test',
                             "automationName": "XCUITest",
                             "noReset": True,   #是否不重新安装启动
                             "udid": "c527ea59a43aabf64f0c088f87b071fdefda7192"
                         })


#此方法判断用户是否已登陆
def check_shouye():

   print('开始判断....')
   try:
       shouye=driver.find_element_by_accessibility_id("tab_dashboard")
   except Exception as e:
       print('no canceBtn')

       print('点击账号登录')
       driver.find_element_by_accessibility_id("login_account").click()
       driver.implicitly_wait(5)
       #输入用户名
       driver.find_element_by_accessibility_id("login_account_account_input").send_keys("1650@qq.com")
       #输入密码
       driver.find_element_by_accessibility_id("login_account_password_input").send_keys("123456")
       #点击登录
       driver.find_element_by_accessibility_id("login_account_login").click()

       print('登录后')
       time.sleep(5)
       driver.find_element_by_accessibility_id("tab_dashboard")
       #点击新建
       TouchAction(driver).tap(x=329, y=571).perform()
       #点击新建文档
       TouchAction(driver).tap(x=63, y=438).perform()
       #定位标题
       TouchAction(driver).tap(x=40, y=120).perform()


   else:
       print('已经登陆了!')

check_shouye()

xpath定位方式在 XCUITest 底层原生不支持,由 appium 额外支持的,定位速度很慢,而且有时候定位不到元素的情况存在。综上所述,在 iOS 的 UI 自动化中,使用原生支持的iOSNsPredicateString定位方式是最好,支持也是最好的。

5、iOSClassChain

仅支持 iOS 10或以上,这是 github 的 Mykola Mokhnach 大神开发,仅限在 WebDriverAgent 框架使用,用于替代 xpath 的,但使用一阵子后,感觉灵活性没有 xpath 和 iOSNsPredicate 好,应该还不完善吧。具体使用方法,请见:https://github.com/appium/appium-xcuitest-driver/pull/391 。

find_element_by_ios_class_chain

代码语言:javascript
复制
    def find_element_by_ios_class_chain(self, class_chain_string):
        """Find an element by ios class chain string.

        Args:
            class_chain_string (str): The class chain string

        Usage:
            driver.find_element_by_ios_class_chain('XCUIElementTypeWindow/XCUIElementTypeButton[3]')

        Returns:
            `appium.webdriver.webelement.WebElement`

        :rtype: `appium.webdriver.webelement.WebElement`
        """
        return self.find_element(by=MobileBy.IOS_CLASS_CHAIN, value=class_chain_string)

以上这个多定位方式。根据我的经验,推荐使用: Android:AndroidUIAutomator > className = id = AccessibilityId > xpath。 iOS:iOSNsPredicateString > className = AccessibilityId> xpath。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-04-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 python粉丝团 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1,accessibility_id
  • 2、class_name
  • 3、xpath
  • 4、ios_predicate
  • 自动处理系统权限弹框
  • 5、iOSClassChain
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档