龙空技术网

软件测试 | XPath高级定位技巧

霍格沃兹测试 83

前言:

此刻大家对“javaxpathhtml”大约比较关切,大家都需要分析一些“javaxpathhtml”的相关知识。那么小编同时在网上汇集了一些有关“javaxpathhtml””的相关资讯,希望咱们能喜欢,朋友们快快来了解一下吧!

通常使用定位工具定位App页面上的元素会发生定位不到元素或者定位元素失败的情况。发生这种情况可能是App的页面不唯一,也可能是App的页面发生了变化。下面介绍定位元素的高级用法,使用层级关系定位或者多重属性定位的方式来确定了App页面元素的唯一性,从而更精准、更稳定地定位到我们想要App页面元素。

1.XPath高级定位技巧

(1)XPath简介

XPath的英文全称为XML Path Language,意为对XML中的元素进行路径定位的一种语言,它使用与XML标记语言、HTML标记语言,App Dom结构。XPath是我们做自动化测试中进行元素定位时用的比较多的工具,它可使用与Seleniu、Appium和Appcrawler。前面章节已经对XPath进行了一些说明,下面只对XPath做举例说明。

(2)XPath基本语法

表5-4是XPath的常用方法。

(3)XPath模糊定位技巧

XPath中的contains()是模糊匹配的定位方法,若在定位元素时,一个元素的属性不固定,这时就可以用模糊匹配来定位元素。使用格式为//[contains(@content-desc,'帮助')],示例代码如下(Python版和Java版)。

Python版

driver.find_element(By.XPATH,'//*[contains(@text,"测试")]')driver.find_element(By.XPATH,'//*[contains(@content-desc,"搜索")]')driver.find_element(By.XPATH,'//*[contains(@resource-id,"login_phone")]')

Java版本

driver.findElement (By.xpath(       "//*[contains(@text,\"测试")]"));      driver.findElement(By.xpath(        "//*[contains(@content-desc,\"搜索"\)]"));        driver.findElement(By.xpath(         "//*[contains(@resource-id,\"login_phone\")]"));

(4)XPath组合定位技巧

用XPath可以同时匹配两个甚至多个属性来完成元素定位。这里常用的属性有text、resource-id、class、index、content-desc等,任意组合这些属性完成定位,示例代码如下(Python版和Java版)。

Python版本

driver.find_element(    By.XPATH,'//*[@text="我的" and @resource-id="tab_name"]'    ).click()    driver.find_element(    By.XPATH,'//*[@text="注册/登录" and @index="1"]    ').click()

Java版本

driver.findElemnt(By.xpath(     "//*[@text=\"我的\ and @resource-id=\"tab_name\"]")).click();     driver.findElement(By.xpath(      "//*[@text=\"注册/登录\" and @index=\"1"]")).click();

(5)XPath层级定位

我们定位元素的时候可能会设计通过子元素去定位父元素,或者用父元素定位子元素,或者定位兄弟元素,XPath支持父子关系、兄弟关系元素的查找与定位。示例代码如下(python版和Java版)。

Python版本

# 通过子元素定位父元素# 方法一: ..driver.find_element_by_xpath(   '//*[@text="手机号"]//..').tag.name   # 方法二:parent::*driver.find_element_by_xpath(    '[@text="手机号"]/parent::*').tag.name    #通过某元素定位其兄弟元素driver.find_element_by_xpath(    '//*[text="手机号"]/../li'    ).tag_name

Java版本

//通过子元素定位父元素//方法一:..driver.findElement(By.xpath(  "//*[@text=\"手机号\"]/..")).getTagName();  //方法二 parent::*driver.findElement(By.xpath(   "[@text=\"手机号\"]/parent::*")).getTagName();   //通过某元素定位其兄弟元素driver.find_Element(By.xpath(    "//*[@text=\"手机号\"]/../li"    )).getTagName();
2.实例案例

(1)场景一

App应用:雪球apk。

我们首先使用UI Automator Viewer工具对该App进行DOM分析,然后使用XPath对分析到的元素进行定位,如图5-14所示的搜索框,我们可以使用元素的多种元素对搜索框进行定位,常用的属性有text、resource-id、class和content-desc等。

这里推荐使用resource-id进行定位,通常情况下,它是App页面元素的卫衣属性,用XPath编程实现定位的代码如下(Python版和Java版)。

Python演示代码

driver.find_element(    By.XPATH,'//*[contains(@resource-id,"tv_search")]') # 或者也可以写成下面这样 driver.find_element(By.ID,'tv_search')

Java演示代码

driver.findElement(By.xpath("//*[contains(@resource-id,        \"tv_search\")]"));//或者也可以写成下面这样driver.findElement(By.id("tv_search"));

(2)场景二

如图5-15所示,获取 “ BABA”所对应的股票价格 “187.11”,可以使用XPath父关系来进行元素定位。

定位实现的代码如下(Python版和Java版)

Python演示代码

curr_price = self.driver.find_element(   MobileBy.XPath,"//*[@text='BABA']/../../..\   //*[@resource-id='com.xueqiu.android:id/current_price']")

Java演示代码

MobileElement curr_price = driver.findElement(      By.xpath("//*[@text=\"BABA\"]/../../..//\      *[@redource-id='com.xueqiu.android:id/current_price']"));
3.UIAutomator定位技巧

UiAutomator是Android SDK自带的一个测试框架,这个测试框架提供了一些列的API,用这些API可以与用Android开发的APP进行交互,例如,打开菜单、点击、滑动等。当Appium的Caps参数uiautomatorName设置为UiAutomator2时,就能够实现计算机端与手机端的UiAutomator通信,并且我们可以使用UiAutomator执行测试代码。UiAutomator1是比较旧的版本,如果想测试较旧版本的基于Android系统开发的App(低于Android 4.4版本),需要设置Appium的Caps参数:uiautomationName="UiAutomator1"。

由于UiAutomator是Android SDK自带的 “工作引擎”,使用这个测试框架进行元素定位,执行速度要比用XPath定位元素快很多。但由于UiAutomator的用法比较特殊,调试起来相对麻烦,如果测试脚本中的定位语句编写不当,脚本编辑器也不会给出任何错误提示信息,只能在运行的时候检验测试脚本的对错。

下面就单独介绍一下基于UiAutomator定位元素的方法,基本语法如下(Python版和Java版)。

Python版本

driver.find_elemnet_by_android_uiautomator()

Java版本

driver.findElement(MobileBy.AndroidUIAutmator());

常用的UiAutomator方法如下:

UiSelenium()   #实现元素定位UiScrollable() #实现滚动查找元素

(1)通过text定位

UiSelector()的用法与XPath类似,可以通过元素的text属性来定位元素。Uiselector的语法格式如下:

new UiSelector().text("text文本")

UiSelector也适用模糊查询的方式来定位元素。

UiSelector的演示代码如下(Python版和Java版)。

Python版本

driver.find_element_by_android_uiautomator(    'new UiSelector().textContains("手机")').click()

Java版本

driver.findElementByAndroidUIAutomator(\    "new UiSelector().textContains(\"手机\")").click();

(2)通过resourceId定位

UiAutomator同样也能用ID定位元素,格式为new UiSelector().resourceId("resource-id属性"),示例代码如下(Python版和Java版本)。

Python版本

driver.find_element_by_android_uiautomator(    'new UiSelector().resourceId("rl_login_phone")').click()

Java版本

driver.findElementByAndroidUIAutomator("new UiSelector().\resourceId(\"rl_login_phone\")").click();

(3)通过className定位

App页面上元素的class属性一般不唯一,此时可以根据下标对元素定位,格式new UiSelector().className("className"),一般使用find_elements完成元素定位,示例代码如下(Python版和Java版)。

Python版本

driver.find_elements_by_android_uiautomator(  'new UiSelector().\  className("android.widget.TestView"))'[5].click()

Java版本

driver.findElementsByAndroidUIAtor("new UiSelector().\className(\"android.widget.TestView\")")[5].click();

(4)通过description定位

description也支持content-desc定位方式,格式为new UiSelector().description("content-des"属性),示例代码如下(Python版和Java版)。

Python版本

driver.find_element_by_android_uiautomator(  'new UiSelector().description("搜索")').click()

Java版本

driver.findElementByAndroidUIAutomator("new \UiSelector().description(\"搜索\")").click();

(5)组合定位方式

UiAutomator也支持属性组合定位元素,示例代码如下(Python版和Java版)。

Python版本

driver.find_element_by_android_uiautomator( 'new UiSelector().resourceId(\ "com.xueqiu.android:id/tv_login_phone").text("手机号")').click();

Java版本

driver.findElementByAndroidUIAutomator("new UiSelector().resourceId(\\"com.xueqiu.android:id/tv_login_phone\").text(\"手机号\")").click();

(6)滚动查找元素

UiAutomator使用 UiScrollable()方法可以滚动查找指定的某个元素,示例代码如下(Python版和Java版)。

driver.find_element_by_android_uiautomator(  'new UiScrollable(new UiSelector().scrollable(true\  .instance(0)).scrollIntoView(new UiSelector()\  .text("我的").instance(0);').)click()

Java版本

driver.findElementByAndroidUIAutomator(\  "new UIScrollable(new UiSelector().scrollable(ture)\  .instance(0)).scrllIntoView(new UiSelector().\  text(\"我的\").instance(0));").click();

上面的测试代码作用是,在当前的页面滚动查找text属性值是 “我的” 这个元素,找到之后执行点击操作。

4.css selector元素定位

Appium Server从1.19.0版本开始,增加了用css selector方式进行元素定位的支持,即appiumuiautomator2-driver会将css selector定位方式转化成UiAutomator定位方式。

注意:Appium Inspector中暂时没有添加这种定位当时。

由于UiSelector()的表达式用的是Java格式的语法,因此编写定位元素的表达式很复杂,且在用工具编写代码时(如Pycharm、VSCode、IntelliJ IDEA等工具),若代码编写错误也不会有任何提示信息。只能是代码运行时才能发现其中表达式的错误。css selector 的语法会自动转成UiAutomator的语法结构,这种官方提供的原生的定位元素的方式,定位速度更快一些。

(1)ID定位

css selector 可以用ID进行元素定位。飞马如下(Python版和Java版)(#igk 表示css selector 定位符)。

Python版本

driver.find_element_by_css_selector('#igt')driver.find_element_by_id_('android:id/igk')

Java版本

driver.findElementByCssSelector("#igk").click();driver.findElementById("android:id/igk").click();

(2)class name定位

css selector使用class name进行元素定位的代码如下(Python版和Java版)(css selector 的定位符为.android.widget.ImageView)。

Python版本

driver.find_element_by_css_selector('.android.widget.ImageView')driver.find_element_by_class_name("android.widget.ImageView")

Java版本

driver.findElementByCssSelector(".android.widget.ImageView");driver.findElementByClassName("android.widget.ImageView");

(3)text定位

css selector 使用text进行元素定位的代码如下(Python版和Java版)(css selector的定位符为“*[text=‘工作台’]”)。

Python版本

driver.find_element_by_css_selector("*[text='工作台']")

注:对应XPath定位器的代码时driver.find_element_by_xpath("//*[@text='工作台']")。

Java版本

driver.findElementByCssSelector("*[text=\"工作台\"]");

注:对应XPath定位器的代码是driver.findElementByXPath("//*[@text= \ "工作台"]").

(4)description定位

css selector使用description进行元素定位的代码如下(Python版和Java版)(css selector的定位符为*[description="ContentDescription"])。

Python版本

driver.find_element_by_scc_selector('*[description="ContentDescription"]')

对应accessibility id定位器的代码如下:

driver.find_element_by_assessibility_id("ContentDescription")

Java版本

driver.findElementByCssSelector("*[description=\"ContentDescription\"]");

对应accessibility id的定位器代码如下:

driver.findElementByAccessibilityId("ContentDescription");

搜索微信公众号:TestingStudio霍格沃兹的干货都很硬核

标签: #javaxpathhtml