一、问题的提出:
使用selenium做自动化测试的一般步骤为:
1) 通过By.id、name、xpath等方法定位页面元素
2) 对定位到的页面元素执行相应的操作
3) 对操作后出现的结果和预期结果做一个比较
使用webdriver做过一段时间的测试就会发现一个对某一个页面的元素进行定位的时候,程序行间充斥着id()、name()、xpath()等方法,这样会造成测试程序的可读性较差,不便于后期的维护以及修改。
虽然我们可以通过添加注释的方法使程序便于理解,但是还是不可以从根本上解决这种问题。我们可以通过对这些方法进行二次封装来避免每次对这些方法的直接调用,通过方法的封装虽然可以实现复用。但是我们发现通过封装无法实现页面元素的逻辑处理和测试数据的独立。
不断地添加新的测试,而极少地去重构、利用原有测试。Selenium的执行速度比较慢(相对单元测试),随着测试逐渐的增多,运行时间会逐渐增加到不可忍受的程度。
思考过之后才知道,直接调用selenium提供的API方法或者对selenium的API进行二次封装后的调用,我们无非是通过调用这些方法来实现对测试页面细节程度的把控,可是真正的逻辑部分我们却未曾独立出来。
二、问题的解决办法:
Page Object模式
Page Object将测试对象及单个的测试步骤封装在每个Page对象中,以page为单位进行管理。
1、例如没有使用Page Object模式时对于163邮箱的登录操作代码如下:
packagecom.test;
importorg.openqa.selenium.By;
importorg.openqa.selenium.WebDriver;
importorg.openqa.selenium.WebElement;
importorg.openqa.selenium.firefox.FirefoxDriver;
publicclasstest163 {
publicstaticvoidmain(String[] args)
{
//启动浏览器,进入163邮箱首页
WebDriver driver =newFirefoxDriver();
driver.get("http://mail.163.com/");
Thread.sleep(5000);
//输入用户名密码,登录邮箱
WebElement youxiangzhanghao_element = driver.findElement(By.id("idInput"));
youxiangzhanghao_element.clear();
youxiangzhanghao_element.sendKeys("justForYourTesting");
WebElement mima_element = driver.findElement(By.id("pwdInput"));
mima_element.sendKeys("135135");
WebElement denglu_element = driver.findElement(By.id("loginBtn"));
denglu_element.click();
Thread.sleep(10000);
driver.close();
}
}
2、使用FindBy注解
package com.mail163;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
public class mail163 {
@FindBy(id="idInput" )
private WebElement username;
@FindBy(id="pwdInput" )
private WebElement password;
@FindBy(id="loginBtn" )
private WebElement loginBtn;
public void login(WebDriver dr,String username,String pwd){
dr.get("http://mail.163.com");
this.username.sendKeys(username);
this.password.sendKeys(password);
loginBtn.click();
}
}
通过FindBy每一个页面元素都被定义为一个类中的私有变量,通过调用login()方法即可实现登陆页面的登录操作。
通过对比1、2明显可以看出,2的逻辑结果比1更加简洁,以每个page为单位(类),以每个page元素为类的属性,以方法login()来实现每个页面元素操作的封装。程序的逻辑独立性更强,也方便后期的维护和修改。
3、对Login类的login方法的初始化
package com.test.java;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.PageFactory;
public class testLogin3 {
public void login1(String username, String password)
{
WebDriver driver= new FirefoxDriver();
// 对页面元素的初始化
login m=PageFactory.initElements(driver, login.class);
m.login(driver, username, password);
}
public static void main(String[] args)
{
testLogin3 tl = new testLogin3();
tl.login1("justForYourTesting","135135");
}
}