加载中…
个人资料
wx小鱼
wx小鱼
  • 博客等级:
  • 博客积分:0
  • 博客访问:751
  • 关注人气:4
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

通过xpath相对路径查找元素方法

(2017-03-02 18:05:28)
分类: 自动化测试
http://blog.csdn.net/zhubaitian/article/details/39754233

一、什么是xpath
XPath 是一门在 XML
文档中查找信息的语言。
XPath 用于在 XML 文档中通过元素和属性进行导航。
       XPath 使用路径表达式来获取 XML 文档中的节点或者节点集。
XPath 包含一个标准函数库 。

二、xpath基本语法:

表达式 描述
nodename 选取此节点的所有子节点。
/ 从根节点选取。
// 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
. 选取当前节点。
.. 选取当前节点的父节点。
@ 选取属性。
路径表达式 结果
/bookstore/book[1] 选取属于 bookstore 子元素的第一个 book 元素。
/bookstore/book[last()] 选取属于 bookstore 子元素的最后一个 book 元素。
/bookstore/book[last()-1] 选取属于 bookstore 子元素的倒数第二个 book 元素。
/bookstore/book[position()<3] 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。
//title[@lang] 选取所有拥有名为 lang 的属性的 title 元素。
//title[@lang='eng'] 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。
/bookstore/book[price>35.00] 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。
/bookstore/book[price>35.00]/title 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。
/div[2]表示第二个,/div[last()]表示最后一个,但是没有/div[first()]的语法,选择第一个用/div[1]
选择一个以上的元素,使用|,如//div|//a,表示选择所有的div标签和a标签
选择未知元素,使用“*”来选择满足条件的所有元素,如/*
//input[@class=’input’]选择元素中的属性
//input[@class]选择有属性名为class的input标签
//input[@]选择有属性的input标签

三、应用实例(Appium根据xpath获取控件

界面有3个TextView类型的控件:

最上面的作为整个ListView的Title文本为“Notes”的TextView,Index为0

中间的文本为“note2”的TextView,Index也是0

最下面的文本为“note1”的TextView,Index是1

现在要通过xpath的方法来定位“note2“这个ListView下面的TextView控件。

1 通过判断控件属性获取控件

控件的所有属性都可以用作判断,比如它的text,index,resource-id是否clickable等,例如:

1.1 通过文本查找目标控件

[java] 
  1. el driver.findElementByXPath("//android.widget.TextView[contains(@text,'note2')]");  
  2.    assertThat(el.getText(),equalTo("note2"));  


1.2 通过index查找目标控件

如果我们像下面的方式使用index为0来查找控件note2,那么将会失败,因为该xpath只是说“我要查找页面上android.widget.TextView类型的index为0的控件“,但如背景所说我们事实上有3个TextView控件,其中最上面的和中间的控件他们的Index都是0.所以最终获得的控件其实是Appium第一个找到的最上面文本为”Notes“的TextView。

[java] 
  1. el driver.findElementByXPath("//android.widget.TextView[contains(@index,0)]");  
  2.    assertThat(el.getText(),equalTo("note2"));  

那么我们就要想办法加多点路径,让xpath能分辨出需要的是下面的index为0的TextView,而不是上面的。观看上图的UIAutomatorViewer控件的分层结构,发现这两个TextView是从LinearLayout开始分叉的,所以我们应该从该路径开始通过数组下标指定我们需要的是”在LinearLayout下面的第二个FrameLayout下面的ListView下面的Index为0的TextView:

[java] 
  1. el driver.findElementByXPath("//android.widget.LinearLayout[1]/android.widget.FrameLayout/android.widget.ListView/android.widget.TextView[contains(@index,0)]");  
  2. assertThat(el.getText(),equalTo("note2"));  



2 通过指定选择集合的位置获得控件

按照我的实践和理解,通过这种方式获取控件是不靠谱的,起码存在两个问题。
  • 问题1:控件在集合中的位置是不可控的。
[java] 
  1. el driver.findElementByXPath("//android.widget.TextView[1]");  
  2. assertThat(el.getText(),equalTo("note2"));  

以上的例子我原意是想把UIAutomatorViewer里面的上中下3个TextView中的中间那个给找出来,但结果返回来给我的确实最上面的那个“Notes”。
  • 问题2:通过增加路径层数限制查找指定元素集合不起效。
[java] 
  1. el driver.findElementByXPath("//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout/android.widget.ListView/android.widget.TextView[0]");  
  2. assertThat(el.getText(),equalTo("note2"));  

以上例子我本意是想通过增加父路径的限制来表明“我想要的控件是ListView下面的那两个TextView控件中的第一个”,但返回给我的是“An unknown server-side error occurred while processing the command",感觉是越界了的样子。

3 xpath用法官方手册

至于其他非主流获的通过xpath取控件的方式,请参考xpath官方手册中文版:http://wenku.baidu.com/link?url=tLdn9X4ucgmzYyKj4dpsgSDbshXEw6W8BTyqQAXd0kTMY6lBQqLiIL9FHtcZmdIeO8o5ZKV-fzlw96mFgvmWZ-qz35EPObyv8hKLTuyxbv3

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有