1.什么是XPathhtml
XPath定位方式是自动化测试定位技术中的必杀技,几乎能够解决全部的定位难题。它是XML Path语言的缩写,主要用于在XML 文档中选择文档中的节点。基于XML树状文档结构,XPath语言能够用于在整颗树中寻找指定的节点。因为网页的HTML代码是一种特殊的XML文档,所以XPath也支持在HTML代码中定位HTML树状文档结构中的节点。它是一种选择器,在firefox中用firepath可查看。ide
2.XPath语法函数
被测试网页的HTML代码(xPathDemo.html下载)测试
<html> <body> <div id="div1"> <input name="div1input"></input> <a href="http://www.sogou.com">搜狗搜索</a> <img alt="div1-img1" src="http://www.sogou.com/images/logo/new/sogou.png" href="http://www.sogou.com">搜狗图片</img> <input type="button" value="查询" /> </div> <br/> <div name="div2"> <input name="div2input"></input> <a href="http://www.baidu.com">百度搜索</a> <img alt="div2-img" src="http://www.baidu.com/img/bdlogo.png" href="http://www.baidu.com">百度图片</img> </div> </body> </html>
(1)使用绝对路径来定位元素spa
例:在被测试网页中,查找第一个div标签中的按钮。firefox
Java定位语句:WebElement button=driver.findElement(By.xpath("/html/body/div/input[@value='查询']")); code
代码解释:/表示根目录,绝对路径。该表达式从HTML代码的最外曾节点逐层查找,最后定位到按钮节点。htm
说明:使用绝对路径定位方式的好处在于能够验证页面是否发生变化。若是页面发生变化,通常会形成原有定位成功的XPaht表达式定位失败,由此可发现网页结构发生了改变。使用绝对路径定位是十分脆弱的,由于即使页面代码发生了微小的变化,也会形成原有的XPath表达式定位失败。在自动化测试的定位中,优先推荐使用相对路径定位方式。blog
(2)使用相对路径来定位元素索引
例:在被测试网页中,查找第一个div标签中的按钮。
Java定位语句:WebElement button=driver.findElement(By.xpath("//input[@value='查询']"));
代码解释:XPath表达式中的“//”表示在HTML文档的所有层级位置进行查找,input[@value="查询"]表示定位显示“查询”两个字的按钮。
说明:相对路径的XPath表达式更简洁,无论页面发生了何种变化,只要input的value值是“查询”两个字就能够被定位到。推荐使用相对路径的XPath表达式,可大大下降测试脚本中定位表达式的维护成本。
(3)使用索引号进行定位
例:在被测试网页中,查找第二个div标签中的“查询”按钮。
XPath表达式://input[2]
代码解释:根据元素类型在页面中出现的前后顺序,可使用序号来查找指定的页面元素。本实例的XPath表达式表示查找页面中第二个出现的input元素,即被测试页面上的按钮元素。
说明:若是使用“//input[1]”,会定位到两个输入框元素,由于每一个div里面均包含input元素,XPath在查找的时候把每一个div节点看成相同的起始层级开始查找,因此使用“//input[1]”表达式会同时查找到两个div节点中的第一个input元素。所以在使用序号进行页面定位元素的时候,须要注意网页HTML代码中是否包含多个层级彻底相同的代码结构,若包含多个则会定位到多个页面元素。
若页面元素常常被发现新增或者减小的状况,不建议使用索引号定位的方式,由于页面变化极可能会让使用索引号的XPath表达式定位失败。
(4)使用页面元素的属性值定位元素实例
在定位页面元素的时候,会遇到各类复杂结构的网页,而且常常出现没法使用ID、name方式定位的状况。若不想使用绝对路径的定位方式,又搞不清楚到底使用什么序号来定位页面元素,那么推荐使用属性值定位元素的方式。
例:尝试定位被测试网页中的第一个图片元素。
Java定位语句:WebElement img=driver.findElement(By.xpath("//img[@alt='div1-img1']"));
代码解释:表达式使用了相对路径定位方式,而且使用了图片的alt属性值来进行定位,经过查看页面的HTML代码可获取图片的alt值。
说明:被测试网页的元素一般会包含各类各样的属性值,而且不少属性值具备惟一性。若能确认属性值发生变动的可能性很低且具备惟一值,强烈建议使用相对路径方式结合属性值定位的方式来编写XPath定位表达式,基于此定位方法可解决99%的页面元素定位难题。
练习:试着去说出下面的定位元素:
(5)使用模糊的属性值定位元素
在自动化测试的实施过程当中,会遇到另一种状况:页面元素的属性值会被动态地生成,即每次看到的页面元素属性值是不同的,此类页面元素会加大定位难度,使用模糊的属性值定位方式可解决一部分此类难题。XPath函数可实现模糊属性值的定位需求。
XPath经常使用函数以下表所示。
XPath函数 | 定位表达式实例 | 表达式解释 |
Starts-with() | //img[starts-with(@alt,'div1')] | 查找图片alt属性开始位置包含"div1"关键字的页面元素 |
Contains() | //img[contains(@alt,'g1')] | 查找图片alt属性包含“g1”关键字的页面元素 |
Contains()函数属于XPath函数的高级用法,使用场景较多,页面元素的属性值只要具备固定不变的几个关键字,即便页面元素的属性值常常发生必定程度的变化,依旧可使用Contians()函数进行定位。
(6)使用XPath的轴(Axis)进行元素定位
轴可定义相对于当前节点的节点集。使用XPath轴(Axis)方式可依据在文档树中的元素相对位置关系进行定位。先找到一个相对好定位的元素,依据它和要定位元素的相对位置进行定位,可解决一些元素难以定位的问题。
语法为:轴名称::节点。
XPath轴关键字 | 轴的含义说明 | 定位表达式实例 | 表达式解释 |
parent | 选择当前节点的上层父节点 | //img[@alt='div2-img2']/parent::div | 查找到alt属性值为div2-img的图片,并基于图片位置找到它上一级的div页面元素 |
child | 选择当前节点的下层子节点 | //div[@id='div1']/child::img | 查找到ID属性值为div1的div页面元素,并基于div的位置找到它下层节点中的img页面元素 |
ancestor | 选择当前节点全部上层的节点 | //img[@alt='div2-img2']/ancestor::div | 查找到alt属性值为div2-img的图片,并基于图片位置找到它上级的div页面元素 |
descedant | 选择当前节点全部下层的节点 | //div[@name='div2']/descendant::img | 查找到name属性值的div页面元素,并基于div的位置找到它下级全部节点中的img页面元素 |
following | 选择在当前节点以后显示的全部节点 | //div[@id='div1']/following::img | 查找到ID属性值为div1的div页面元素,并基于div的位置找到他后面节点中的img页面元素 |
following-sibling | 选择当前节点以后的全部平级节点 | //a[@href='http://www.sogou.com']/following-sibling::input | 查找到连接地址为http://www.sogou.com的连接页面元素,并基于连接的位置找到它同级节点中的input页面元素 |
preceding | 选择当前节点前面的全部节点 | //img[@alt='div2-img2']/preceding::div | 查找到alt属性值为div2-img2的图片页面元素,并基于图片的位置找到它前面节点中的div页面元素 |
preceding-sibling | 选择当前节点前面的全部同级节点 | //img[@alt='div2-img2']/preceding-sibling::a[1] | 查找到alt属性值为div2-img2的图片页面元素,并基于图片的位置找到它前面同级节点中的第二个连接页面元素 |
(7)使用页面元素的文原本定位元素
使用text()函数能够定位到包含某些关键字的页面元素。
说明:使用文字匹配模式进行定位,为定位复杂的页面元素提供了一种强大的定位模式,在遇到定位困难的时候,可优先使用此方法进行定位。建议使用此定位方式进行大量练习,作到可随意定位到页面中的任意元素。
3.总结
(1)经常使用符号说明
(2)路径表达式查看
在网页元素上,点击鼠标右键,选择“Inspect in File Path”,可查看某个网页元素的xpath路径。例如,定位百度首页的“新闻”元素。
(3)函数
//div[contains(@id,'in')],表示选择id中包含有'in'的div节点
<a class="baidu" href="http://www.baidu.com">baidu</a>
查找节点的文本值为baidu的超连接,//a[text()='baidu']
//input[@name='identity' or @class='Volvo'][last()],取最后一个
//div[starts-with(@id,'in')],表示选择以id属性为'in'开头的div节点
//input[@name='identity' and not(contains(@class,'A'))],表示匹配出name为identity而且class的值中不包含A的input节点
//input[not(@id)],匹配出input节点不含有id属性的节点。
(4)xpath轴练习
以axisDemo2网页(下载)为例,进行讲解
//div[@id='radio']//label[text()='Saab']/preceding-sibling::input是什么意思?
//input[following-sibling::label[text()='Saab']]是什么意思?