package page;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.CacheLookup;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class BDPage {
@FindBy(id="kw"
)
@CacheLookup
public WebElement keyword_input;
@FindBy(id="su"
)
@CacheLookup
public WebElement search_button;
public BDPage(WebDriver driver){
PageFactory.initElements(driver, this);
}
}
元素声明的写法,这三行是一个整体:
@FindBy(id="kw"
)
@CacheLookup
public WebElement keyword_input;
注解:
@FindBy:这个定义了你所查找的元素是以什么方式 定位的,比如图中我用的是id,那么就写成 @FindBy(id=”kw”),
还有其他几种写法:@FindBy(name=”xx”)、@FindBy(className=”xx”)、@FindBy(xpath=”xxx”)、@FindBy(css=
”xxx”)等
@CacheLookup:意思是说找到元素之后将缓存元素,重复的使用这些元素,将使测试的速度大大加快。
WebElement keyword_input:就是变量名
二、PageFactory
public BDPage(WebDriver driver){
PageFactory.initElements(driver, this);
}
PageFactory是为了支持页面设计模式而开发出来的,它的方法在selenium.support库里面。
它提供初始化页面元素的方法,如果页面存在大量的AJAX的技术,只要页面更新一次,它就好重新查找一次元素,所以不
会出现StaleElementException这个error,
页面设计模式,可以提供你一个接口,然后你在这个接口上面,构建你自己项目中的页面对象,使用PageFactory使得测
试更简单,更少的代码编写。
如果@FindBy没有指定,它会默认的查找id的属性,然后是name属性,如果还没有找到就会报错。 如果这个元素存在,
我们不用担心它, pageFactory会初始化这个元素,不会报任何错误。
二、selenium流行的设计模式page object
selenium目前比较流行的设计模式就是page object,那么到底什么是page object呢,简单来说,就是把页面作为对象,
在使用中传递页面对象,来使用页面对象中相应的成员或者方法,能更好的提现java的面向对象和封装特性。而使用时间长了
会发现该模式也存在一点问题,那就是元素每次都要获取,并且获取元素与页面方法不分离,增加代码冗余度,用过springMVC框架
的人都知道,注解方式的开发会大大增加开发效率,使页面变得整洁。
本次要介绍的就是pageFactory 设计模式,什么是pageFactory 设计模式呢?
准确来说就是在page object模式基础上更好的利用了面向对象的思维,将获取元素与操作页面的方法进行分离,以前获取
元素要findelementbyid等等,现在只要一个注解就可以搞定,并且再次跑自动化回归测试时候,代码有获取缓存的特性,
所以会比第一次跑的快,只要id,name不变。
1
.首先介绍FindBy类:
For example, these two annotations point to the same element:
@FindBy(id = "f"
) WebElement f;
@FindBy(how = How.ID, using = "f"
) WebElement f;
and these two annotations point to the same list of elements:
@FindBy(tagName = "a") List<WebElement>
links;
@FindBy(how = How.TAG_NAME, using = "a") List<WebElement>
links;
用来分别查找单个元素和多个元素的两种用法,支持的类型有:className、css、id、linkText、name、
partialLinkText、tagName、xpath。
How支持的类型和上面差不多。
2
.接着介绍PageFactory类
Factory class to make using Page Objects simpler and easier.
它提供的方法都是静态的,可以直接调用,我们在用完findby后,需要进行元素初始化,则需要调用下面的方法
initElements(ElementLocatorFactory factory, java.lang.Object page)、initElements(FieldDecorator
decorator, java.lang.Object page)、initElements(WebDriver driver, java.lang.Class<T>
pageClassToProxy)、
initElements(WebDriver driver, java.lang.Object page)
我们在实际使用中可以这样用:
PageFactory.initElements(dr, XXX.class);
或者
PageFactory.initElements(new AjaxElementLocatorFactory(dr, 10) ,XXX.
class);
后者加入了初始化元素时等待时间。
3
.下面给大家简单用个例子介绍我的设计模式。
public class BasePage {
WebDriver driver;
private final int TIMEOUT=3
;
public BasePage(WebDriver driver )
{
this.driver=
driver;
PageFactory.initElements(new AjaxElementLocatorFactory(driver, TIMEOUT) ,
this);
}
public BasePage(WebDriver driver,
final String title)
{
this.driver=
driver;
WebDriverWait wait=
new WebDriverWait(driver, TIMEOUT);
try{
boolean flag = wait.until(
new ExpectedCondition<Boolean>
(){
@Override
public Boolean apply(WebDriver arg0) {
// TODO Auto-generated method stub
String acttitle =
arg0.getTitle();
return acttitle.equals(title);
}});
}catch(TimeoutException te) {
throw new IllegalStateException("当前不是预期页面,当前页面title是:" +
driver.getTitle());
}
PageFactory.initElements(new AjaxElementLocatorFactory(driver, TIMEOUT) ,
this);
}
这是我的基础页面,以后任何页面都继承该页面,因为判断UI层次的页面标题。
2
.登录页面
public class LoginPage
extends BasePage {
@FindBy(id="ele_active_close"
)
@CacheLookup
private WebElement wd;
@FindBy(id="at_index_login-box_mobile"
)
@CacheLookup
private WebElement inputusername;
@FindBy(id="at_index_login-box_password"
)
@CacheLookup
private WebElement inputpassword;
@FindBy(id="at_index_login-box_p_forget_login"
)
@CacheLookup
private WebElement mybutton;
public LoginPage(WebDriver driver) {
// TODO Auto-generated constructor stub
super(driver);
}
public LoginPage(WebDriver driver, String title) {
super(driver, title);
// TODO Auto-generated constructor stub
}
//不设定homepage类型不行,因为返回的是这个对象 必须是这个类型
public HomePage login(){
JbClose();
username(""
);
password(""
);
mybutton();
return new HomePage(driver,"xxx);
}
public void username(String username)
{
inputusername.clear();
inputusername.sendKeys(username);
}
public void password(String password)
{
inputpassword.clear();
inputpassword.sendKeys(password);
}
public void mybutton()
{
mybutton.click();
}
public void JbClose()
{
wd.click();
}
}
3
.登录后要进入什么页面
public class HomePage
extends BasePage{
public HomePage(WebDriver driver) {
super(driver);
// TODO Auto-generated constructor stub
}
public HomePage(WebDriver driver,String title)
{
super(driver,title);
}
}
4
.下面就是main方法了,实际中建议和testng混合使用
public class TestFactory {
public static void main(String[] args) {
WebDriver driver=
new ChromeDriver();
driver.get("http://petrocoke-web-test.obaymax.com/"
);
String logintitle="xxx"
;
LoginPage lg=
new LoginPage(driver, logintitle);
HomePage hm=
lg.login();
System.out.println("测试结束"
);
driver.quit();
}
}
三、selenium之设计模式POM
https://blog.csdn.net/u011541946/article/details/75393386
https:
//me.csdn.net/u011541946
前面介绍了POM的优点和非POM方式写脚本,这篇介绍利用页面工厂类(page factory)去实现POM,
通过查看PageFactory类,我们可以知道它是一个初始化一个页面实例的功能,在实例化该页面对象时候,
也会一起实例化该页面的元素定位。直接来看看京东登录的例子,如果用POM实现,在测试脚本中实际代码就2行。
1
.在pageObjects包新建一个京东主页类,代码如下
package pageObects;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
public class JdHomePage {
// 元素定位
//登录链接
@FindBy (id="ttbar-login"
)
WebElement login_link;
//账户登录
@FindBy (xpath="//*/div[@class=‘login-form‘]/div[2]/a"
)
WebElement login_withAccount;
//输入用户名框
@FindBy (id="loginname"
)
WebElement inputBox_username;
//输入密码
@FindBy (id="nloginpwd"
)
WebElement inputBox_password;
//登录按钮
@FindBy (id="loginsubmit"
)
WebElement login_submitBtn;
// 业务逻辑和操作方法
//登录方法
public void login(String username, String password){
login_link.click();
login_withAccount.click();
inputBox_username.sendKeys(username);
inputBox_password.sendKeys(password);
login_submitBtn.click();
}
}
2
.在testSuites包下新建一个测试类
package testSuites;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.PageFactory;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import pageObects.JdHomePage;
public class TestWithPOM {
WebDriver driver;
@BeforeClass
public void setUp()
throws Exception{
System.setProperty("webdriver.chrome.driver", ".\\Tools\\chromedriver.exe"
);
driver =
new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://www.jd.com/"
);
Thread.sleep(2000
);
}
@Test
public void testLogin(){
JdHomePage hp = PageFactory.initElements(driver, JdHomePage.
class);
hp.login("user1", "123456"
);
}
}
处理打开浏览器和打开京东主页操作,实际测试登录的代码就2行对不对。这里我们借助了PageFactory类的方法,在初始化一
个页面类的时候,也会一起把该页面定义的元素定位也会初始化,然后通过页面对象调用页面类的页面操作方法。这种方式,我们把元素
定位和业务逻辑操作都写在了页面对象类中,测试脚本类,直接调用页面类的方法,这样的测试脚本看起来很简洁,方便阅读和维护,如果
登录相关文案发生变更,我们只需要去改登录对应页面的元素定位和业务逻辑,不需要修改这个登录测试类。
Java+Selenium做UI自动化中@FindBy和@CacheLookup用法【多测师_王sir】
标签:quit app tor keyword get pass 速度 特性 als