8.By Xpath
XPath 是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素和属性进行遍历,而HTML又正好可以看做是XML的一种实现,因此我们便可以用xpath来定位元素啦。
问题:一般刚开始学定位的时候很多人都会想,都有了上面那么多种定位方式了,还要xpath干吗?感觉还挺复杂的样子(和其他的定位方式相比却是要复杂那么一丢丢)~
答:那是因为并不是所有的元素都“如您所愿”,就如上面警察抓捕罪犯的例子,有时候元素并不能直接提供给我们想要的定位。
常用路径表达式:
举几个简单的栗子
1)绝对路径定位:
做测试开发或者有编程经验的小伙伴一定对绝对路径不陌生,通过绝对路径就是使用元素在页面上的完整路径。
还是以定位一周内的最热门帖子为例,在Chrome浏览器的开发者工具栏中,找到要定位元素的HTML位置,右击会出现Copy full Xpath,点击它。
然后我们把复制到的内容黏贴后如下:
/html/body/div[2]/div[2]/div/div[2]/div[1]/div[2]/div[1]/div/a
写到代码里就是这样:
WebDriver driver = new ChromeDriver();
driver.findElement(By.xpath("/html/body/div[2]/div[2]/div/div[2]/div[1]/div[2]/div[1]/div/a"));
可以用又臭又长来形容了,那么细心的小伙伴会发现还有一个Copy xpath,复制黏贴后内容如下:
//*[@id="main"]/div/div[2]/div[1]/div[2]/div[1]/div/a
看起来好像简化了点,还用上了xpath的语法,但是实际上也没优化多少,依然是通过标签的层级关系,从最外层一级一级的往下找,也不是很可取;
其实不可取的最主要原因还是这种绝对路径的方式在实际自动化过程中很不稳定,界面的位置发生任何一丢丢的变化,那元素的绝对路径就很可能变了,也就无法准确定位了。
因此我们就要用元素的属性或者属性和层级关系相结合的方式来定位,这样就算页面变化,只要变化不是非常大,依然可以通过元素的属性和相对的位置来进行定位,受页面位置变化的影响就要小的多了。
2)元素属性定位:
定位testerhome首页的欢迎,利用xpath语法通过id来定位:
WebDriver driver = new ChromeDriver();
driver.findElement(By.xpath("//div[@id='c-button']"));
语法解释://div表示从当前页面的div标签开始匹配,@id表示用id属性值,=后面跟着具体的id值。
3)属性和层级关系定位:
上面的通过属性定位完全可以用WebDriver的API或者CSS搞定,xpath最大的价值就是上面说的当元素没有直接可定位的属性时,它的价值才得以完美体现:
现在我们要定位”七日最热 Top10“这个标题,它只有class属性,我们按照className来进行定位会发现如下情况:
没错,出现了10个可被定位到的元素,因为有很多的标题都有相同的classname,并且没有其他如id,name等属性了;没办法了,我们就要往上找,我们发现往上2个div标签节点,classname为”col-md-3 home-side-bar“的标签节点是唯一的:
现在我们就利用Xpath先定位到唯一的那个class,然后往下找两层div,再取两层后div中的第一个就可以了。
WebDriver driver = new ChromeDriver();
driver.findElement(By.xpath("//*[@class='col-md-3 home-side-bar']/div[1]/div[1]"));
4)使用Xpath运算符定位:
WebDriver driver = new ChromeDriver();
driver.findElement(By.xpath("//*[@class='col-md-3 home-side-bar']/div[1]/div[1]"));Xpath还支持运算符,如果元素的一个属性无法定位,需要使用多个属性时可以使用Xpath运算符将多个属性连接起来一起定位。
Xpath常用运算符
现在需要定位testhome社区首页一篇最新帖子的作者,作者名为“乌云乌云快走开” 如果我们只依靠className的话会发现有28个相同属性的元素,如下图:
继续观察会发现还有一个叫做data-name的属性,属性值就是作者的姓名,我们通过and符将两个属性连接后便发现可以精准定位到指定元素了:
WebDriver driver = new ChromeDriver();
driver.findElement(By.xpath("//a[@class='user-name' and @data-name='乌云乌云快走开']"));
5)使用Xpath函数定位:
Xpath还提供了很多函数来供我们更灵活的定位,这里以我常用的一个contains函数为例。
我们依旧来定位testerhome首页七日最热贴的首贴“[深圳][头条] 招聘测试 leader”,通过对DOM的分析可以看到title属性的内容就是帖子的标题,我们用此属性值的一部分来作为定位条件:
WebDriver driver = new ChromeDriver();
driver.findElement(By.xpath("//*[contains(@title,'[深圳][头条]')]"));
9.By CSS
Web页面的样式通常保存在外部的 .css 文件中。通过仅仅编辑一个简单的 CSS 文档,外部样式表使你有能力同时改变站点中所有页面的布局和外观。因此我们可以利用CSS的选择器来定位页面绑定了属性的元素,从而为我们的selenium所用。
从上面的文章一路看下来的小伙伴应该发现了,在介绍xpath之前的定位方式时,都另外还写了一个CSS的定位方式,没错,就是它,没注意的小伙伴可以返回去看一看;
推荐使用CSS: CSS也是我们在Web自动化中最推荐使用的一种方式,原因又如下几种:
·例如id这种元素在一个页面中可能并不唯一,并且很有可能是前端的框架自动生成的,研发人员并未对其进行维护,随时可能变;而CSS是前端开发最常用的一种维护方式,对于我们开发和维护自动化用例也更为清晰和方便。
· 大部分定位都可以用CSS来解决。
· CSS的写法相较于Xpath要更为简洁。
常用的CSS选择器语法:
先将前面已经演示过的CSS语法在这来个小的汇总:
· 通过id
WebDriver driver = new ChromeDriver();
driver.findElement(By.cssSelector("#cornertip")); //CSS
·通过className
WebDriver driver = new ChromeDriver();
driver.findElement(By.cssSelector(".form-control"));
· 通过name
WebDriver driver = new ChromeDriver();
driver.findElement(By.cssSelector("[name='q']"));
· 通过tag name
WebDriver driver = new ChromeDriver();
driver.findElement(By.cssSelector("input"));
· 通过link text
WebDriver driver = new ChromeDriver();
driver.findElement(By.cssSelector("a[title='[深圳][头条] 招聘测试 leader']"));
· 通过partialLinkText
WebDriver driver = new ChromeDriver();
driver.findElement(By.cssSelector("[title~='[深圳][头条]']"));
另外CSS也可以将属性和层级关系组合在一起进行使用,现在我们以这种组合方式来定位testerhome社区置顶帖的第一篇帖子:
WebDriver driver = new ChromeDriver();
driver.findElement(By.cssSelector(".panel-heading+div>div>div.topic-20857"));
简要说明: .panel-heading:class值为panel-heading +div : 后面紧接着的div >div:后面所有子的div div.topic-20857:class名为topic-20857的div标签。
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理