appium元素定位(12)

来源:互联网 发布:在淘宝上买东西的流程 编辑:程序博客网 时间:2024/05/22 06:51

自动化测试来说,核心技能就是对象的定位。不管是 web 页面上的一个
按钮或输入框,还是移动 app 上的一个按钮或输框,我们要想对其进行点击或输入操作,前提是要先找到这个对象。对于手工测试来说,是由测试人员来完人了,人通过眼睛与大脑来识别一个按钮或输入框,但自动测试工具没有这种能力,但是一个对象一定会有一些属性(如 id、class 等),自动化测试工具就是靠着这些属性来识别和查找对象。webdriver 提供了八种元素定位方法:
l id
l name
l class name
l tag name
l link text
l partial link text
l xpath
l css selector
Python 语言中对应的定位方法如下:
find_element_by_id()
find_element_by_name()
find_element_by_class_name()
find_element_by_tag_name()
find_element_by_link_text()
find_element_by_partial_link_text()
find_element_by_xpath()
find_element_by_css_selector()
一组元素定位的方法如下:
find_elements_by_id()
find_elements_by_name()
find_elements_by_class_name()
find_elements_by_tag_name()
find_elements_by_link_text()
find_elements_by_partial_link_text()
find_elements_by_xpath()
find_elements_by_css_selector()
Appium 完全继承了 WebDriver 中所定义的这些方法,除此之外对其进行了扩展,以便适合移动端对象的定位与操作 

 

定位的工具

uiautomatorviewer:Android SDK自带的一个工具,在tools目录下

monitor:Android SDK自带的一个工具,在tools目录下

Appium Inspector:Appium自带的一个功能,只有mac下可以使用该功能

 

定位详解

通过id定位

(取resource-id的值):

driver.find_element_by_id("com.wuba.zhuanzhuan:id/azo")

也可以直接用id后面的内容driver.find_element_by_id("azo")

 

通过class_name定位

(取class的内容)

driver.find_element_by_class_name("android.widget.RelativeLayout")

 

通过xpath定位

(取xpath得内容)

driver.find_element_by_xpath("//android.widget.LinearLayout[1]/android.widget.XXX")

 

通过text定位

(需要使用uiautomator的定位方式,使用text的内容)

driver.find_elements_by_android_uiautomator("new UiSelector().text(\"+关注\")")

 

使用这里需要注意一下,通过text定位的结果是个list,不能直接click。所以如果要点击需要取数组的值,比如下面是点击找到的第一个元素

driver.find_elements_by_android_uiautomator("new UiSelector().text(\"+关注\")")[0].click()

 

通过css_selector定位(webview)

只适用于webview的html页面,继承自webdriver,与pc版本的UI测试一致

driver.find_element_by_css_selector()

 

通过link_text定位(webview)

只适用于webview容器中的html页面,继承自webdriver,与pc版本的UI测试一致

driver.find_element_by_link_text()

 

通过name定位

web view容器中的html页面可以用name定位,native并没有name属性

driver.find_element_by_name()

  

2.定位元素的另一种写法:find_element(by,value)

find_element_by_方式(value)实际调用的都是find_element(by,value)

需要导入这个包:from selenium.webdriver.common.by import By

 

例如:定位id为ag2的元素

方式一:driver.find_element_by_id("ag2)

方式二:driver.find_element(By.ID,"ag2")

 

这个操作的好处是可以直接把操作的by和value放到一个元组里,然后调用通用方法来传参获得元素结果

cateid=(By.ID,"ag2")

driver.find_element(*cateid).click()

 

by的操作可以是:

By.ID   相当于by_id

By.CLASS_NAME  相当于by_class_name

By.XPATH   相当于by_xpath

By.NAME   相当于by_name

By.TAG_NAME   相当于by_tag_name

By.CSS_SELECTOR  相当于by_css_selector

By.LINK_TEXT  相当于by_link_text

 

 

3.find_elements_by_定位方式(value)返回元素数组

用法与find_element_by_方式(value)一致,但是返回一个数组。可以通过数组的索引来访问具体的某个结果

 

例如:通过class_name定位到多个元素,我想点击第一个元素

driver.find_elements_by_class_name("android.widget.RelativeLayout)[0].click()

 

4.返回元素数组的另一种写法:find_elements(by,value)

用法与find_element(by,value)一致,但是返回一个数组。可以通过数组的索引来访问具体的某个结果

 

例如:通过class_name定位到多个元素,我想点击第一个元素

driver.find_elements(By.CLASS_NAME,"android.widget.RelativeLayout)[0].click()

 

5.通过元素定位元素

可以先找到某个元素,然后再进一步定位元素

find_element_by_class_xpath(“xxx”).find_element_by_name(“yyy")

 

UiSelector

  概述:

    按照一定的条件(例如控件的text值,资源id),定位界面上的元素。UiSelector对象的最终目的是去构造一个UiObject对象。

  摘要:

1、根据text构造:

函数返回值

函数体

说明

用法

UiSelector

text(String text)

根据“控件text属性的内容”构造出UiSelector对象

例如,一个控件text的值是“发现”,UiSelector s = new UiSelector().text("发现");

UiSelector

textContains(String text)

根据“控件text属性包含的内容”构造出UiSelector对象

同上例子:UiSelector s = new UiSelector().textContains("现");

UiSelector

textMatches(String regex) 

根据“控件text属性正则表达式的内容”构造出UiSelector对象

正则表达式语法参考网上资料即可。

UiSelector

textStartsWith(String text)

根据“控件text属性开始的内容”构造出UiSelector对象

同上例子:UiSelector s = new UiSelector().textStartsWith("发");

      比较常用,准确度也比较高,中文查找的时候,如果遇到 “UiOjbectNotFoundException” 的时候,记得把项目的编码格式改为utf-8。

 

2、根据description构造:

UiSelector

description(String desc)

根据“控件content-desc属性的内容”构造出UiSelector对象

UiSelector

descriptionContains(String desc)

包含**

UiSelector

descriptionMatches(String regex)

正则

UiSelector

descriptionStartsWith(String desc)

以**开始

 

      同text的用法基本一致,也是比较靠谱的一种方式。

 

3、根据资源id:

UiSelector

resourceId(String id)

根据资源id获取对象,例如:UiSelector s = new UiSelector().resourceId("com.tencent.mm:id/b8m")

UiSelector

resourceIdMatches(String regex)

根据资源id的正则表达式获取对象

 

4、根据类:

UiSelector className(String  className):

        根据控件的类名来找到UiSelector对象。


        但是呢?因为一般Android布局的时候,同样的控件类名都是一样的。

        因此我在微信的登录界面调用: UiSelector s = new UiSelector().className("android.widget.TextView") 这句话,它得到的就是我左上开始算第一个class名称为“android.widget.TextView”的控件。

       

UiSelector instance (int instance):

        上面提到的假如我们想获取屏幕上电话号码的那个TextView使用这样方法,就可以使用instance:

   UiSelector s = new UiSelector().className("android.widget.TextView").instance(1);

UiSelector index(int index):

        用法和上面的instance差不多,谷歌的原文说这个方法是unreliable的,推荐使用instance方法。

UiSelector childSelector(UiSelector selector):

        有的时候假如子控件不好获得,而其父控件比较好获得的时候,我们通常采用这样的方式,例如下面:


           我们目前选中的是LinearLayout,这个Android中的一种布局,它的里面嵌套了两个控件,一个是ImageView,另一个是EditText。这们这里就通过LinearLayout这个控件找到它的子控件。

        很明显,父控件id已经给定。我们先得到父控件:UiSelector s_p = new UiSelector().resourceId("com.tencent.mm:id/axj");

        其次 UiSelector s_c= s_p.childSelector( new UiSelector().className("android.widget.EditText") );

        在它的父控件的childSelector方法中传入一个带有一定特征的UiSelector对象,即可得到子控件,这里 s_c 就是输入框的UiSelector对象。

UiSelector fromParent(UiSelector selector):

        有的时候父控件也不好获得,而是同级的控件(同属一个parent)比较好获取,那么使用这样方法,还拿上面的举例:

        我们先得到EditText的UiSelector对象:UiSelector s1 = new UiSelector().resourceId("com.tencent.mm:id/axc");

        得到和它同样一个父控件的ImageView的UiSelector对象:UiSelector s2 = fromParent( new UiSelector().className("android.widget.ImageView") );

5、根据特有属性:

UiSelector

checked(boolean val)

根据是否可check来构造出UiSelector对象

UiSelector

chickable(boolean val)

 

UiSelector

enabled(boolean val)

 

UiSelector

focusable(boolean val)

 

UiSelector

longClickable(boolean val)

 

UiSelector

scrollable(boolean val)

 

UiSelector

selected(boolean val)

 

      举个简单的例如,假如当前的界面,只有一个checkbox是勾选状态,你就可以这样得到:UiSelector s2 = new UiSelector().checked(true)

 

原创粉丝点击