全段时间学完的POM(Page Object Model) 没有总结发到博客上来,今天总结下,就当自己在复习一遍.
介绍POM:
页面对象模型(Page Object Model)在Selenium Webdriver自动化测试中使用非常流行和受欢迎.本篇介绍POM的简介,接下来一步一步告诉你如何在你Java+Selenium自动化测试框架中实现POM。
Selenium中使用POM的特点和优点?
1) POM是一种设计模式,它能帮我们维护代码和减少代码的重复,这个在自动化测试领域是一个很重要的话题。
2) 在具体实施中,一个页面看做一个页面对象,每个页面写一个类。
3) 你可以把一个页面的元素的全部定位方式和该页面的业务操作方法写在一个类文件,然后在测试脚本类文件去调用页面类的元素和方法。这样就有一个 好 处,你的软件产某一个界面出现了变化,你只需要修改对应页面的元素定位和相关方法,而不需要去修改你的测试脚本,当然除非你这个页面由于需 求问题,之后被砍了,你才要去修改你的测试脚本类。
4) 在POM中,我们把测试脚本和页面对象分层,例如页面对象统一放一个包下面,测试用例脚本统一放另外一个包下,到达测试脚本和页面对象分离。
不使用POM:
不使用POM模式,我们写的代码:
package testSuites; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; public class TestNoPOM { 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() { // 点击登录 driver.findElement(By.id("ttbar-login")).click(); // 点击账号登录 driver.findElement(By.xpath("//*/div[@class='login-form']/div[2]/a")).click(); // 输入用户名 driver.findElement(By.id("loginname")).sendKeys("user1"); // 输入密码 driver.findElement(By.id("nloginpwd")).sendKeys("password"); //点击登录 driver.findElement(By.id("loginsubmit")).click(); } @AfterClass public void tearDown(){ driver.quit(); } }
上面脚本中,包含了元素定位和业务逻辑操作方法,两者混合在一起,如果脚本注释写得不好,在代码数量小的时候寻找问题还是没什么难度的,但是如果写了很多脚本的时候,根本没有层次和逻辑可言。让维护脚本的新人会很头疼.
使用POM模式:
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 WebDriver driver; // 业务逻辑和操作方法 //登录方法 public void login(){ driver.manage().window().maximize(); driver.get("https://www.jd.com/"); Thread.sleep(2000); login_link.click(); login_withAccount.click(); inputBox_username.sendKeys("username"); inputBox_password.sendKeys("password"); login_submitBtn.click(); } public void Quit(){ driver.quit(); } public JdHomePage(){ driver=new FirefoxDriver(); PageFactory.initElements(driver,this); } }
在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 { @Test public void testLogin(){ JdHomePage jhp =new JdHomePage(); jhp.login(); jhp.quit(); } }
这种方式,我们把元素定位和业务逻辑操作都写在了页面对象类中,测试脚本类,直接调用页面类的方法,这样的测试脚本看起来很简洁,方便阅读和维护,如果登录相关文案发生变更,我们只需要去改登录对应页面的元素定位和业务逻辑,不需要修改这个登录测试类。
使用LoadableComponent类:
继承这个类会需要重写load(),isload()两个方法,可以再加载的时候判断时候被正确加载.
load()方法中的代码一般是用来写跳转到某个页面,如driver.get(url)
isLoaded() 方法中的代码一般是用来验证页面是否加载完成并成功
则该类的代码改为:
package t0320; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.ui.LoadableComponent; import org.testng.Assert; public class BaiduHomePage extends LoadableComponent<BaiduHomePage> { //百度首页的页面工厂 @FindBy(xpath = ".//*[@id='kw']") private WebElement inputBox; //输入框 @FindBy(xpath = ".//*[@id='su']") private WebElement searchButton; //搜索按钮 @FindBy(xpath = ".//*[@id='1']/h3/a") private WebElement encyclopedia; //中国_百度百科元素 private String baiduUrl = "https://www.baidu.com/"; //百度首页的地址 private String baiduOnce = "百度一下,你就知道"; //百度首页的标题 private WebDriver driver; public BaiduHomePage(){ //构造函数,生成浏览器对象,初始化PageFactory对象 // System.setProperty("webdriver.firefox.marionette", "src/main/resourcec/geckodriver.exe"); driver = new FirefoxDriver(); PageFactory.initElements(driver, this); } @Override protected void load() { //打开百度 driver.get(baiduUrl); driver.manage().window().maximize(); System.out.println("执行load方法!"); } @Override protected void isLoaded() throws Error{ //断言浏览器是否打开了正确的网址 System.out.println("执行isLoad方法!!"); Assert.assertTrue(driver.getTitle().equals(baiduOnce)); } public void quit(){ //结束driver driver.quit(); } public void searchChina(){ //封装搜索“中国”的步骤 inputBox.sendKeys("中国"); //输入“中国” searchButton.click(); //点击搜索按钮 } public String getText(){ //封装获取中国_百度百科元素的文本 return encyclopedia.getText(); } }
package t0320; import org.testng.Assert; import org.testng.annotations.Test; public class BaiduSearchCase { @Test //搜索“中国”的测试用例 public void baiduSearch() throws InterruptedException { BaiduHomePage baiduHomePage = new BaiduHomePage(); //生成一个BaiduHomePage对象实例 baiduHomePage.get(); baiduHomePage.searchChina(); Thread.sleep(2000); Assert.assertEquals(baiduHomePage.getText(), "中国_百度百科"); baiduHomePage.quit(); } }
看看这段代码的执行结果就会明白:
首先会执行isload判断是否正确加载了页面,没有执行load方法,在执行isload进行判断!!这样可以加强我们的页面访问操作!!
用非PageFactory实现POM(记录):
这个方法是我最近看别人博看突然看到的,我也不知道这种方法有什么好处?(给我的感觉是写起来没有简单反而很麻烦了!)但是还是在这里记录下吧!防止以后不时之需!!
package pageObects; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; public class JdHomePage { WebDriver driver; // 元素定位 //登录链接 By login_link = By.id("ttbar-login"); //账户登录 By login_withAccount = By.xpath("//*/div[@class='login-form']/div[2]/a"); //输入用户名框 By inputBox_username = By.id("loginname"); //输入密码 By inputBox_password = By.id("nloginpwd"); //登录按钮 By login_submitBtn = By.id("loginsubmit"); // 业务逻辑和操作方法 // 构造方法 public JdHomePage(WebDriver driver){ this.driver = driver; } //点击登录链接 public void clickLoginLink(){ driver.findElement(login_link).click(); // 点击账户登录,不点击的话默认是二维码扫描登录 driver.findElement(login_withAccount).click(); } // 登录步骤拆分-输入用户名 public void inputUsername(String username){ driver.findElement(inputBox_username).sendKeys(username); } // 登录步骤拆分-输入密码 public void inputPassword(String password){ driver.findElement(inputBox_password).sendKeys(password); } // 点击登录按钮 public void clickLoginBtn(){ driver.findElement(login_submitBtn).click(); driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS); } //重构一个登录方法 public void login(String name, String pass){ driver.findElement(login_link).click(); // 点击账户登录,不点击的话默认是二维码扫描登录 driver.findElement(login_withAccount).click(); driver.findElement(inputBox_username).sendKeys(name); driver.findElement(inputBox_password).sendKeys(pass); driver.findElement(login_submitBtn).click(); driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS); } }
2.测试类内容如下
package testSuites; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; 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 = new JdHomePage(driver); hp.clickLoginLink(); hp.inputPassword("user1"); hp.inputUsername("123456"); hp.clickLoginBtn(); } }
还没有评论,来说两句吧...