浅析selenium的page object模式

selenium目前比较流行的设计模式就是page object,那么到底什么是page object呢,简单来说,就是把页面作为对象,在使用中传递页面对象,来使用页面对象中相应的成员或者方法,能更好的提现java的面向对象和封装特性,首先看一下官网的解释:

Page Object Design Pattern

Page Object is a Design Pattern which has become popular in test automation for enhancing test maintenance and reducing code duplication. A page object is an object-oriented class that serves as an interface to a page of your AUT. The tests then use the methods of this page object class whenever they need to interact with the UI of that page. The benefit is that if the UI changes for the page, the tests themselves don’t need to change, only the code within the page object needs to change. Subsequently all changes to support that new UI are located in one place.

The Page Object Design Pattern provides the following advantages

1. There is a clean separation between test code and page specific code such as locators (or their use if you’re using a UI Map) and layout.

2. There is a single repository for the services or operations offered by the page rather than having these services scattered throughout the tests.

In both cases this allows any modifications required due to UI changes to all be made in one place. Useful information on this technique can be found on numerous blogs as this ‘test design pattern’ is becoming widely used. We encourage the reader who wishes to know more to search the internet for blogs on this subject. Many have written on this design pattern and can provide useful tips beyond the scope of this user guide. To get you started, though, we’ll illustrate page objects with a simple example.

First, consider an example, typical of test automation, that does not use a page object.

/***
 * Tests login feature
 */
public class Login {

        public void testLogin() {
                selenium.type("inputBox", "testUser");
                selenium.type("password", "my supersecret password");
                selenium.click("sign-in");
                selenium.waitForPageToLoad("PageWaitPeriod");
                Assert.assertTrue(selenium.isElementPresent("compose button"),
                                "Login was unsuccessful");
        }
}

There are two problems with this approach.

  1. There is no separation between the test method and the AUT’s locators (IDs in this example); both are intertwined in a single method. If the AUT’s UI changes its identifiers, layout, or how a login is input and processed, the test itself must change.
  2. The ID-locators would be spread in multiple tests, in all tests that had to use this login page.

Applying the page object techniques, this example could be rewritten like this in the following example of a page object for a Sign-in page.

/**
 * Page Object encapsulates the Sign-in page.
 */
public class SignInPage {

        private Selenium selenium;

        public SignInPage(Selenium selenium) {
                this.selenium = selenium;
                if(!selenium.getTitle().equals("Sign in page")) {
                        throw new IllegalStateException("This is not sign in page, current page is: "
                                        +selenium.getLocation());
                }
        }

        /**
         * Login as valid user
         *
         * @param userName
         * @param password
         * @return HomePage object
         */
        public HomePage loginValidUser(String userName, String password) {
                selenium.type("usernamefield", userName);
                selenium.type("passwordfield", password);
                selenium.click("sign-in");
                selenium.waitForPageToLoad("waitPeriod");

                return new HomePage(selenium);
        }
}

and page object for a Home page could look like this.

/**
 * Page Object encapsulates the Home Page
 */
public class HomePage {

        private Selenium selenium;

        public HomePage(Selenium selenium) {
                if (!selenium.getTitle().equals("Home Page of logged in user")) {
                        throw new IllegalStateException("This is not Home Page of logged in user, current page" +
                                        "is: " +selenium.getLocation());
                }
        }

        public HomePage manageProfile() {
                // Page encapsulation to manage profile functionality
                return new HomePage(selenium);
        }

        /*More methods offering the services represented by Home Page
        of Logged User. These methods in turn might return more Page Objects
        for example click on Compose mail button could return ComposeMail class object*/

}

So now, the login test would use these two page objects as follows.

/***
 * Tests login feature
 */
public class TestLogin {

        public void testLogin() {
                SignInPage signInPage = new SignInPage(selenium);
                HomePage homePage = signInPage.loginValidUser("userName", "password");
                Assert.assertTrue(selenium.isElementPresent("compose button"),
                                "Login was unsuccessful");
        }
}


官网中使用的代码例子是selenium1的方式,为了方便我使用webdirver做了实现,并使用知乎登录作为例子。

思路:

A:打开浏览器

B:访问www.zhihu.com

C:登录

D:登录后,主页验证是否登录成功

以上四个步骤用到了2个页面,登录页面和主页,下面我们就对这两个页面进行封装。

1.新建一个HomePage类。

package com.pageobject1;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.testng.Assert;

/**
 * @author QiaoJiafei
 * @version 创建时间:2016年2月26日 上午10:01:51
 * 类说明
 */
public class HomePage {
    private WebDriver driver;
    WebElement element_account;

    public HomePage(WebDriver driver) {
        if(!driver.getTitle().equals("首页 - 知乎")) {
            throw new IllegalStateException("This is not Home Page of logged in user, current page" +
                    "is: " +driver.getTitle());
        }
        element_account = driver.findElement(By.id(":0"));
    }

    public HomePage manageProfile() {
        // Page encapsulation to manage profile functionality
        String text = element_account.getText();
        Assert.assertEquals(text, "乔叶叶");
        return new HomePage(driver);
}
}

2.新建一个LoginPage类

package com.pageobject1;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;

import com.google.common.base.Predicate;

/**
 * @author QiaoJiafei
 * @version 创建时间:2016年2月26日 上午9:55:23
 * 类说明
 */
public class LoginPage {

    private WebDriver driver;
    WebElement element_username;
    WebElement element_password;
    WebElement element_submit;

    public LoginPage(WebDriver driver) {
        // TODO Auto-generated constructor stub
        this.driver = driver;
        if(!driver.getTitle().equals("知乎 - 与世界分享你的知识、经验和见解")) {
            throw new IllegalStateException("This is not sign in page, current page is: "
                    +driver.getTitle());
        }
        element_username = driver.findElement(By.name("account"));
        element_password = driver.findElement(By.name("password"));
        element_submit =  driver.findElement(By.xpath("/html/body/div[1]/div/div[2]/div[2]/form/div[3]/button"));
    }
    public HomePage loginValidUser(String userName, String password) {
        element_username.sendKeys(userName);
        element_password.sendKeys(password);
        element_submit.click();
        WebDriverWait wait = new WebDriverWait(driver, 10);
        wait.until(new ExpectedCondition<WebElement>(){

            @Override
            public WebElement apply(WebDriver arg0) {
                // TODO Auto-generated method stub
                return arg0.findElement(By.id(":0"));
            }

        }).isDisplayed();     //注意根据实际业务,返回相应页面对象
        return new HomePage(driver);
}
}

3.新建一个测试类

package com.pageobject1;

import java.sql.Driver;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

/**
 * @author QiaoJiafei
 * @version 创建时间:2016年2月26日 上午10:20:29
 * 类说明
 */
public class TestLogin {
    WebDriver driver = null;
    @BeforeClass
    public void beforeClass() {
        String key = "webdriver.firefox.bin";
        String value = "C:/Program Files (x86)/Mozilla Firefox/firefox.exe";
        System.setProperty(key, value);
        driver = new FirefoxDriver();

        driver.manage().window().maximize();
        driver.get("https://www.zhihu.com/#signin");
    }

    @AfterClass
    public void afterClass() {
        driver.quit();
    }

    @Test
    public void testLogin() {

        LoginPage loginPage = new LoginPage(driver);
        HomePage homePage = loginPage.loginValidUser("[email protected]", "XXXXX");
        /*
         * 下面就可以使用homepage对象来做操作,如:
         * homePage.manageProfile();
         *
         * */
        Assert.assertEquals(driver.getTitle(), "首页 - 知乎");
    }
}

由此可见,在测试类中,操作的基本都是页面对象,逻辑清晰,代码简单,在后期的维护中,如果那个页面的元素发生变化,则只需要更改相应页的页面类即可,不需要更改测试类的逻辑。

看到这里有的也许会问:每次都要求返回一个页面对象,有时不确定怎么办?

我的解决办法是:在实际的自动化测试中,是先有测试用例,后编写测试脚本,所以基本每个页面传递对象都可以确定,如在主页我点击一篇文章会跳转一个文章页面,点击个人头像灰跳转一个个人页面,在就是在主页类中写两个方法,一个方法返回文章页面,一个方法返回个人页面,依次类推……

好了,这篇文件就先简单介绍一下page object的设计思想及用法,以后会写一篇文章,如何在框架中使用这种模式

时间: 2024-11-10 01:05:24

浅析selenium的page object模式的相关文章

Python+Selenium使用Page Object实现页面自动测试 -未完待续

Page Object模式是Selenium中的一种测试设计模式,主要是将每一个页面设计为一个Class,其中包含页面中需要测试的元素(按钮,输入框,标题 等),这样在Selenium测试页面中可以通过调用页面类来获取页面元素,这样巧妙的避免了当页面元素id或者位置变化时,需要改测试页面代码的情况. 当页面元素id变化时,只需要更改测试页Class中页面的属性即可. Page Object模式是一种自动化测试设计模式,将页面定位和业务操作分开,提高用例的可维护性. unittest是一种单元测试

python+ selenium&amp;APPium page Object 设计模式

题记: 之前公司项目比较稳定, 在进行了系统测试,想用自动化测试进行冒烟测试,或者对主要功能进行测试, 因此用到了PO模式 因此做个记录: Page Object Page Object模式是使用Selenium的广大同行最为公认的一种设计模式.在设计测试时,把元素和方法按照页面抽象出来,分离成一定的对象,然后再进行组织. Page Object模式,创建一个对象来对应页面的一个应用.故我们可以为每个页面定义一个类,并为每个页面的属性和操作构建模型.体现在对界面交互细节的封装,测试在更上层使用页

python+selenium自动化软件测试(第7章):Page Object模式

什么是Page ObjectModel模式Page Objects是selenium的一种测试设计模式,主要将每个页面看作是一个class.class的内容主要包括属性和方法,属性不难理解,就是这个页面中的元素对象,比如输入用户名的输入框,输入登陆密码的输入框,登陆按钮,这个页面的url等,而方法,主要是指这个页面可以提供的具体功能.为什么选择POM?我们先看一段简单的代码如下: from selenium import webdriver import time driver = webdri

Test Automation With Selenium Using Page Object Design

WebDriver IntroductionA different way of automating the browser.. Create a browser-specific driver to control the browser directly and have to do this for each browser. Object oriented API. Doesn't need a real browser. No JavaScript limitations. No n

安卓自动化测试:Robotium(二)page object 模式完善测试框架

1.目前比较流行的设计模式就是page object,page object就是把页面作为对象,在使用中传递页面对象,来使用页面对象中相应的成员或者方法,能更好的提现java的面向对象和封装特性2.具体思想:测试框架分为四大类1)编写抽象父类:建立Utils包,存放工具类,用于自动完成唤醒手机.解锁.登录等前置操作,之后的用例只需继承抽象父类即可2)提取控件ID类:在工程中建立从com.pacagename.test.elements包用例存放控件ID类.命名一般以Element开头,后面接Ac

selenium(六)Page Object模式(使用selenium的PageFactory)

PageObject 类 import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; public class PageObject { private String url="http://www.baidu.com&qu

web自动化中的page object模式

一. 原理 将页面的元素定位和元素行为封装成一个page类,实现页面对象和测试用例分离 类的属性:元素定位 类的行为:元素的操作 测试用例:调用所需页面对象中的行为,组成测试用例 二. 好处 1. 当某个页面的元素发生变化,只需要修改该页面对象中的代码即可,测试用例不需要修改 2. 提高代码重用率,结构清晰,维护代码更容易 3. 测试用例发生变化时,不需要或者只需要修改少数页面对象代码即可 三. 分析 (待续...) 原文地址:https://www.cnblogs.com/cnhkzyy/p/

Page Object设计模式

1. 什么是框架 1.1 定义: 框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件(类)及构件(类)实例间交互的方法. 1.2 为什么要搭建自动化测试框架 自动化测试的开发,通常是由自动化测试的需求决定的.这个需求主要包括: 自动化测试更便于实施 解决自动化测试脚本本身存在的问题,如异常处理和场景恢复. 测试易于维护.好的框架,可以减少你在管理维护中所投入的人力物力精力. 可重用性.框架的意义之一就在于可重用吧.所以在框架里,你可以实现一些通用功能,简化脚本开发过程. 

Page Object封装思想

文章来源:http://blog.csdn.net/zhenyu5211314/article/details/13632083 Page Object模式是Selenium中的一种测试设计模式,主要是将每一个页面设计为一个Class,其中包含页面中需要测试的元素(按钮,输入框,标题等),这样在Selenium测试页面中可以通过调用页面类来获取页面元素,这样巧妙的避免了当页面元素id或者位置变化时,需要改测试页面代码的情况.当页面元素id变化时,只需要更改测试页Class中页面的属性即可. 获取