元素定位方法
在Web UI自动化测试过程中,通常的要完成测试用例编写需要进行如下几步:
- 找到Web的页面元素,并把定位路径保存在一个对象中
- 对操作对象进行操作,比如:点击、输入、回车等。
- 指定页面元素操作的值,比如输入什么,执行某个操作。
所以UI 界面交互的自动化测试就是动作、对象、数值的结合,所以我们要对一个页面进行操作,必须先找到要操作的对象,如果找不到页面元素,那么步骤2,步骤3都无法进行。并且在大多数的项目实践中,由于Web页面技术的复杂性以及前端的频繁改动,造成大量的页面元素很难定位或者变动,造成自动化用例无法编写或者执行失败。
因为Selenide底层还是Selenium,所以定位方法相同如下:
按照在以往项目经验中,按照优先使用的优先级顺序排序
定位方法 |
定位方式 |
Selenide使用方法 |
使用id定位 |
Id值 |
#kw |
使用name定位 |
Name值 |
byName("password") |
使用cssName定位 |
元素Class属性的值 |
.welcome-message |
使用xpath定位 |
Xpath表达式 |
byXpath("//*[@id='search-results'] |
使用css定位 |
Css的表达式 |
byCssSelector("#kw") |
使用链接的文字定位 |
link的全部文字内容 |
byLinkText("link") |
使用标签名称定位 |
Html的标签名称 |
|
使用jquery定位 |
Js.executeScript(“return jQery.find(‘jquery表达式’)”) |
总结以往的项目经验,最常用的定位方式为ID/Name/Xpath这三种定位方式就足够满足95%以上的元素定位了,所以这里只对这三种方式将一下,其他的可以自我了解并灵活运用在实际工作中。
为了方便练习元素定位,这里简单写一个demo供练习使用
如何查看以及定位网页元素呢,常见的浏览器IE/Chrome/Firefox都提供元素查看的的插件,可以很直观的看到页面html结构树,目前使用最多的是chrome浏览器,所以已chrome为例打开上面的demo页面,找到我们需要定位的元素,然后右击点开查看元素就可以看到元素的id/name/class属性,并可以观察 到html结构
我通常情况下要定位一个元素大概分为三步:
1. 通过查找id/name定位
查看元素是否存在id/name属性,这是比较简单高效的方法,并且相对于其他定位方式相对稳定,观察页面username输入框可以id定位,值为input,lastname输入框可以用name定位,值为lastname,如果不存在id/name,则尝试通过xpath查找
2. 通过xpath表达式定位
什么是Xpath?(取自w3school,如果要了解更多内容,可以去w3school上看看)
XPath 是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素和属性进行遍历。
XPath 路径表达式
XPath 使用路径表达式来选取 XML 文档中的节点或者节点集。这些路径表达式和我们在常规的电脑文件系统中看到的表达式非常相似。
备注:当然也有很多人推荐使用css,原因可能有两个:1,xpath的查找速度比css慢一些;2,在IE浏览器下,css的兼容性比xpath好。当时我觉得xpath比css灵活很多,并且更容易上手。
Xpath分为绝对路径定位以及相对路径的定位方式,绝对路径方法从根元素写起,当元素层级很深的时候,路径写的会很长,阅读性不好,也维护成本高。在非特殊情况下不建议使用(当然我在接触的项目需求也存在需要绝对路径处理的特殊场景,后面会在博客补充),所以也不写例子了,下面都是都是相对路径的例子,一步步学习。
Xpath是通过路径表达式来获取元素节点,下面是常用的路径表达式符号:
表达式 |
描述 |
/ |
表示绝对路径,从根节点选取。 |
// |
从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 |
. |
取当前节点。 |
.. |
选取当前节点的父节点。 |
@ |
选取属性 |
* |
表示通配符 |
[] |
属性的条件表达式 |
通过xpath相对定位方式验证Username输入框
表达式为//input[@id=’ input’] 理解为,通过xpath寻找id属性为input ‘的input元素。
如何验证xpath是否正确呢?在chrome下非常方便,点击到查看元素的html节点上按Ctrl+F,则弹出如下搜素框
输入我们写好的xpath表达式,观察结果,在html结构中查找到的元素节点高亮为黄色,在搜索框的右侧显示查找结果的节点总数,可以通过向上/向下查找元素
常用xpath表达式的使用例子
/html/input 查找html节点下的input标签元素,注意/代表是绝对路径
/html//input 查找html节点下所有的input标签元素,//代表是相对路径,所有会查找所有的input节点
//input 同上
//div/input 查找div节点下的子节点input标签元素
//div//input 查找div节点下所有节点的input标签元素,参考前两个表达式
//div/input/. .表示当前节点,所以可以理解为//div/input
//div/input/.. .. 表示为上层节点,所以可以理解为//div
//input[@id=’ input’] 理解为,通过xpath寻找id属性为input ‘的input元素
//input[@id=’ input’]/a理解为,通过xpath寻找id属性为input ‘的input节点下的a标签元素
//input[1] 查找html页面中的一个input标签
Xpath常用函数的表达式例子
//button[starts-with(@class,'button')] 表示class属性已button开头的button元素节点,常用于动态生成的class元素定位中
(//button)[last()] 表示页面最后一个button元素节点
//button[contains(@class,'button')] 表示class属性包括button字符串的button元素节点
//a[contains(text(),'Google')] 表示元素文本值包含Google字符串的a元素节点,常用于动态生成的class元素定位
这些都是常用的xpath的定位方式,如果还不能解决问题,那么再看看xpath轴
3. 通过xpath轴定位
XPath 轴
轴可定义相对于当前节点的节点集。请结合下面xpath轴关键字的解释以及树结构理解示例的xpath表达式
轴名称 |
结果 |
ancestor |
选取当前节点的所有先辈(父、祖父等)。 |
ancestor-or-self |
选取当前节点的所有先辈(父、祖父等)以及当前节点本身。 |
attribute |
选取当前节点的所有属性。 |
child |
选取当前节点的所有子元素。 |
descendant |
选取当前节点的所有后代元素(子、孙等)。 |
descendant-or-self |
选取当前节点的所有后代元素(子、孙等)以及当前节点本身。 |
following |
选取文档中当前节点的结束标签之后的所有节点。 |
namespace |
选取当前节点的所有命名空间节点。 |
parent |
选取当前节点的父节点。 |
preceding |
选取文档中当前节点的开始标签之前的所有节点。 |
preceding-sibling |
选取当前节点之前的所有同级节点。 |
self |
选取当前节点。 |
常用xpath轴的例子:
表达式示例 |
表达式解释 |
//img[@alt=’div2-img2’]/ancestor::div |
查找到alt属性值为div2-img的图片,并且基于当图片位置找到它上级的所有div元素 |
//div[@name=’div2’]/descendant::img |
查找到name属性值的div页面上元素,并基于div的位置找到它下级所有节点中的img页面元素。 |
//div[@id=‘div1’]//following::img |
查找到id属性值为div1的div元素,并基于div1找到它后面节点中的img元素 |
//img[@alt=‘div2-img2’]/preceding::div |
查找到alt属性值为div2-img2的img,并基于图片的位置到找它前面节点中的div页面元素。 |
//img[@alt=‘div1-img]/ following-sibling::a |
查找到属性为div1-img的img元素并在它前面的同级节点中查找a标签元素 |
//input[@alt=‘div1-input’]/ following-sibling::a |
查找到属性为div1-input的input元素并在它后续同级节点中查找a标签元素 |
在 UI层的自动化测试用例编写的时,其实我们大部分时间都在定位元素,并且自动化测试的元素定位一直是困扰自动化测试新手的一个障碍,因为在自动化实施过程中会碰到各式各样的对象元素,各种前端技术,所以元素的定位方式不至上面提到的这些,我们需要更灵活的调整定位方式。如何提高UI元素的稳定性和可维护性仍然是当前最值得思考的问题。
任务目标:
把上面所有提到的xpath定位表达式在testDemo页面上练习一遍,并且自己要补充其他定位方式的知识,真的很重要~!