自动化测试之元素定位

做自动化测试最基础的就是要先找到待操作的元素,有八种定位方法,下面会一一介绍。

1、什么是元素:HTML 元素指的是从开始标签(start tag)到结束标签(end tag)的所有代码。

2、查找一个元素driver.findElement(By.XX(“XXX”));
查找一组元素driver.findElements(By.XX(“XXX”));

3、By.name()
源码如下:当我们要用name属性来引用这个button并点击它时,代码如下:

public class SearchButtonByName { 
    public static void main(String[] args){ 
        WebDriver driver = new FirefoxDriver(); 
        driver.get("http://www.forexample.com"); 
        WebElement searchBox = driver.findElement(By.name("btnK")); 
        searchBox.click();
}
}

只要该元素的任意一个属性是唯一的,即可通过该属性进行定位,上面用到的是by.name,所以通过name进行定位。

4、By.id()
页面源码如下:

<button id="gbqfba" aria-label="Google Search" name="btnK" class="gbqfba">
<span id="gbqfsa">Google Searchspan>
button>

要引用该button并点击它时,代码如下:

public class SearchButtonById {
    public static void main(String[] args){
        WebDriver driver = new FirefoxDriver();
        driver.get("http://www.forexample.com");
        WebElement searchBox = driver.findElement(By.id("gbqfba"));
        searchBox.click();
}
}

5、By.tagName()
tag有标签的意思,html中

等都是标签,by.tagName()可以通过标签名查找元素。该方法可以通过元素的标签名称来查找元素。这个方法搜索到的元素通常不止一个,所以一般结合findElements方法使用。比如我们现在要查找页面上有多少个button,就可以用button这个tagName来进行查找,代码如下:

public class SearchPageByTagName{
    public static void main(String[] args){
        WebDriver driver = new FirefoxDriver();
        driver.get("http://www.forexample.com");
        List buttons =driver.findElements(By.tagName("button"));
    System.out.println(buttons.size()); 
    //打印出button的个数
    }
} 

另外,在使用tagName方法进行定位时,需要注意有些HTML元素的tagName是相同的,例如单选框、复选框、文本框、密码框等会使用input标签。这样单靠tagName无法准确地得到我们想要的元素,需要结合type属性准确定位。示例代码如下:

public class SearchElementsByTagName{
    public static void main(String[] args){
        WebDriver driver = new FirefoxDriver();
        driver.get("http://www.forexample.com");
        List allInputs = driver.findElements(By.tagName("input"));
        //只打印所有文本框的值
        for(WebElement e: allInputs){
        if (e.getAttribute(“type”).equals(“text”)){
        System.out.println(e.getText().toString()); 
        //打印出每个文本框里的值
}    }
}
}

5、By.className()
className属性是利用元素的css样式表所引用的伪类名称来进行元素查找的方法。对于任何HTML页面的元素来说,一般程序员或页面设计师会给元素直接赋予一个样式属性或者利用css文件里的伪类来定义元素样式,使元素在页面上显示时能够更加美观。引用样式如下:

如果此时我们要通过className属性来查找该button并操作它的话,就可以使用className属性了,代码如下:

public class SearchElementsByClassName{
    public static void main(String[] args){
        WebDriver driver = new FirefoxDriver();
        driver.get("http://www.forexample.com");
        WebElement searchBox = driver.findElement(By.className("buttonStyle"));
        searchBox.sendKeys("Hello, world");
}
}

注意:使用className来进行元素定位时,有时会碰到一个元素指定了若干个class属性值的“复合样式”的情况,例如:
button:
这个button元素指定了三个不同的css伪类名作为它的样式属性值,用 . 连接不同的css伪类名即可。

driver.findElement(By.cssSelector("button.btn.btn_big.btn_submit"))

6、By.linkText()
这个方法比较直接,即通过超文本链接上的文字信息来定位元素,这种方式一般专门用于定位页面上的超文本链接。通常一个超文本链接会长成这个样子:

<a href="/intl/en/about.html">About Googlea>

我们定位这个元素时,可以使用下面的代码进行操作:

public class SearchElementsByLinkText{ 
    public static void main(String[] args){ 
        WebDriver driver = new FirefoxDriver(); 
        driver.get("http://www.forexample.com"); 
        WebElement aboutLink = driver.findElement(By.linkText("About Google")); 
        aboutLink.click(); 
} }

7、By.partialLinkText()
这个方法是上一个方法的扩展。当你不能准确知道超链接上的文本信息或者只想通过一些关键字进行匹配时,可以使用这个方法来通过部分链接文字进行匹配。
代码如下:

public class SearchElementsByPartialLinkText{ 
    public static void main(String[] args){ 
        WebDriver driver = new FirefoxDriver(); 
        driver.get("http://www.forexample.com"); 
        WebElement aboutLink = driver.findElement(By.partialLinkText("About")); 
        aboutLink.click(); 
} } 

注意:使用这种方法进行定位时,如果页面中不止一个超链接包含About时,findElement方法只会返回第一个查找到的元素,而不会返回所有符合条件的元素。如果你要想获得所有符合条件的元素,还是只能使用findElements方法。

8、By.xpath()
这个方法是非常强大的元素查找方式,使用这种方法几乎可以定位到页面上的任意元素。在正式开始使用XPath进行定位前,我们先了解下什么是XPath。XPath是XML Path的简称,由于HTML文档本身就是一个标准的XML页面,所以我们可以使用XPath的语法来定位页面元素。
我们以所示HTML代码为例:



"loginForm">
"username" type="text">
"password" type="text">
"username" type="text">
"continue" type="submit" value="Login">
"continue" type="submit" value="Clean">


Xpath绝对路径写法如下:引用页面上的form元素:/html/body/form[1]
a.元素的xpath绝对路径可通过firebug直接查询。FireFox上也可以使用FirePath插件获取Xpath路径。chrome上选中元素,点击鼠标右键以Xpath的方式进行copy。
b.一般不推荐使用绝对路径的写法,因为一旦页面结构发生变化,该路径也随之失效,必须重新写。
c.当xpath的路径以/开头为绝对路径,表示让Xpath解析引擎从文档的根节点开始解析。Xpath中/表示寻找父节点的直接子节点
e.当xpath路径以//开头为相对路径,则表示让xpath引擎从文档的任意符合的元素节点开始进行解析。Xpath中//表示寻找父节点下任意符合条件的子节点,不管嵌套多少层级。
f.Xpath的路径中可以绝对路径和相对路径混合在一起来进行表示。
g.使用逻辑符号连接两个属性//input[@id=’aa’ and @class=’bb’]/span/input

Xpath相对路径的写法:
a.查找页面根元素://
b.查找页面上所有的input元素://input
c.查找页面上第一个form元素内的直接子input元素(即只包括form元素的下一级input元素,使用绝对路径表示,单/号)://form[1]/input
d.查找页面上第一个form元素内的所有子input元素(只要在form元素内的input都算,不管还嵌套了多少个其他标签,使用相对路径表示,双//号)://form[1]//input
e.查找页面上第一个form元素://form[1]
f.查找页面上id为loginForm的form元素://form[@id=’loginForm’]
g.查找页面上具有name属性为username的input元素://input[@name=’username’]
h.查找页面上id为loginForm的form元素下的第一个input元素://form[@id=’loginForm’]/input[1]
i.查找页面具有name属性为contiune并且type属性为button的input元素://input[@name='continue'][@type='button']
j.查找页面上id为loginForm的form元素下第4个input元素://form[@id=’loginForm’]/input[4]

Xpath功能很强大,所以也可以写得更加复杂一些,如下图的HTML源码。
自动化测试之元素定位_第1张图片
如果我们现在要引用id为“J_password”的input元素,该怎么写呢?我们可以像下面这样写:

WebElement password = driver.findElement(By.Xpath("//*[@id='J_login_form']/dl/dt/input[@id='J_password']"));

也可以写成:

WebElement password = driver.findElement(By.Xpath("//*[@id='J_login_form']/*/*/input[@id='J_password']"));

这里解释一下,其中//*[@id='J_login_form']是指在根元素下查找任意id为J_login_form的元素,此时相当于引用到了form元素。后面的路径必须按照源码的层级依次往下写。我们要找的input元素包含在一个dt标签内,而dt又包含在dl标签内,所以中间必须写上dl和dt两层,才到input这层。当然我们也可以用*号省略具体的标签名称,但元素的层级关系必须体现出来,我们不能写成//*[@id='J_login_form']/input[@id='J_password']

前面讲的都是xpath中基于准确元素属性的定位,其实xpath作为定位神器也可以用于模糊匹配。下图代码中的“退出”这个超链接,没有标准id元素,只有一个rel和href不好定位。我们用xpath的三种模糊匹配模式来定位它:
自动化测试之元素定位_第2张图片
a. 用contains关键字,定位代码如下:
这句话的意思是寻找页面中href属性值包含有logout这个单词的所有a元素,由于这个退出按钮的href属性里肯定会包含logout,所以这种方式是可行的,也会经常用到。其中@后面可以跟该元素任意的属性名。

driver.findElement(By.xpath(“//a[contains(@href, ‘logout’)]”));

b. 用start-with,定位代码如下:
这句的意思是寻找rel属性以nofo开头的a元素。其中@后面的rel可以替换成元素的任意其他属性。

driver.findElement(By.xpath(“//a[starts-with(@rel, ‘nofo’)]));

c. 用Text关键字,定位代码如下:
这个方法可谓相当霸气啊。直接查找页面当中所有的退出二字,根本就不用知道它是个a元素了。这种方法也经常用于纯文字的查找。

driver.findElement(By.xpath(“//*[text()=’退出’]));

注意:Xpath这种定位方式,webdriver会将整个页面的所有元素进行扫描以定位我们所需要的元素,所以这是一个非常费时的操作,如果你的脚本中大量使用xpath做元素定位的话,将导致你的脚本执行速度大大降低,所以请慎用。

9、By.cssSelector()
cssSelector这种元素定位方式跟xpath比较类似,但执行速度较快,而且各种浏览器对它的支持都相当到位,所以功能也是蛮强大的。
自动化测试之元素定位_第3张图片

自动化测试之元素定位_第4张图片
简单的语法看图即可,来个复杂的。定位id为flrs下的href属性值为/forexample/about.html的元素,可以写成: #flrs > a[href=”/forexample/about.html”],如果需要指定多个属性值时,可以逐一加在后面,如#flrs > input[name="username"][type="text"]
明白基本语法后,我们来尝试用cssSelector方式来引用图1中选中的那个input对象,代码如下:

WebElement password = driver.findElement(By.cssSelector("#J_login_form>dl>dt>input[id=’ J_password’]"));

同样必须注意层级关系,这个不能省略。此外,cssSelector还有一些高级用法,熟练后可以更加方便地帮助我们定位元素,我们可以利用^用于匹配一个前缀,$用于匹配一个后缀,*用于匹配任意字符。如表格2

最后总结一下,各种方式在选择的时候应该怎么选择:
a.当页面元素有id属性时,最好尽量用id来定位。但由于现实项目中很多程序员其实写的代码并不规范,会缺少很多标准属性,这时就只有选择其他定位方法。
b.xpath很强悍,但定位性能不是很好,所以还是尽量少用。如果确实少数元素不好定位,可以选择xpath或cssSelector。
c.当要定位一组元素相同元素时,可以考虑用tagName或name。
d.当有链接需要定位时,可以考虑linkText或partialLinkText方式。

下面的代码是我写的关于CSDN自动登录的代码:

package javaSelenium;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class CsdnCreatBlog 
{
    public static void main (String[] args){
        //设置浏览器驱动
        System.setProperty("webdriver.chrome.driver","/Users/liqingju/Downloads/chromedriver");
        //获取URL
        WebDriver driver = new ChromeDriver();
        driver.get("http://write.blog.csdn.net/postlist");
        //输入用户名和密码
        WebElement username = driver.findElement(By.xpath("//input[@id='username']"));
        username.clear();
        username.sendKeys("username");
        WebElement password = driver.findElement(By.xpath("//input[@id='password']"));
        password.clear();
        password.sendKeys("password");
        //点击登录
        waitTime(2000);
        WebElement logging = driver.findElement(By.xpath("//input[@class='logging']"));
        logging.click();
        waitTime(2000);
        //创建博客
        WebElement searchBox = driver.findElement(By.xpath("//ul[@class='tabs']/li[10]/a"));
        searchBox.click();

    }

    private static void waitTime(int i) {
        // TODO Auto-generated method stub

    }

}
文章部分引用于测试控的[Selenium Webdriver元素定位的八种常用方式](http://www.cnblogs.com/qingchunjun/p/4208159.html),码字不易,向作者致敬。
在学习使用的过程中我会不断优化文章,保持更新。
最后希望您转载请注明出处!

你可能感兴趣的:(自动化测试)