Web自动化测试Selenium_博客已迁移测试自动化_博客已迁移

14 Web 自动化测试 -- PageObject 思想

2018-07-03  本文已影响103人  博客已迁移I米阳

到这节课为止我们已经基本上把WebDriver和TestNG的基础都讲完了,下去开始讲讲实战过程中我们会用到的一些思想和工具。

例如这节我们要讲的PageObject思想。相信如果现在你们的脚本已经经过几个迭代的修改了,你们一定会遇到一个头痛的问题,那就是页面变化,以前脚本的定位方式不能用了,得修改定位方式,那如果以往的脚本没有用PageObject思想,意味着你得一个一个Case中把需要修改的定位方式找出来,然后再进行修改。这不但照成脚本维护的成本加大,也可能照成大量代码冗余。

那这时候PageObject就显得尤为重要。 那什么是PageObject呢?

什么是PageObject思想

PageObject 见名思意,就是页面对象。说白就是把页面元素定位和页面元素操作分开。
PageObject在实战过程中我们回对脚本实现进行分层。通常做法是分三层:

  1. 对象库层
  2. 逻辑层
  3. 业务层

对象层用于存放我们的页面元素和一些特殊控件操作。逻辑层则是一些封装好的功能用例模块。业务层则是我们真正的测试用例的操作。

当然如果我们的测试数据量大时,我们还可以在三层基础上再加一层 数据层,用于存放我们的测试数据,这也是比较常规的做法。

  1. 对象库层
  2. 逻辑层
  3. 业务层
  4. 数据层

实战例子

废话不多说我们直接来看个例子,我们还是以163邮箱登录为例子。

对象库层

首先我们新建个叫LoginPage的类,编写登录页面所有可能需要操作的元素定位方式和操作,代码示例如下:

package com.selenium.pageobjcet;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Created by 米阳 on 14/10/2017.
 */
public class LoginPage {

    // 定位 ifrmae
    public static By loginFrame = By.id("x-URS-iframe");
    // 定位 邮箱地址输入框
    public static By emailField = By.name("email");
    // 定位 密码输入框
    public static By pwdFiled = By.name("password");
    // 定位 登录按钮
    public static By loginBtn = By.id("dologin");


    WebDriver driver;

    public LoginPage(WebDriver driver) {
        this.driver = driver;
    }

    /**
     * 往邮箱文本框输入邮箱
     * @param email 邮箱地址
     */
    public void sendKeysEmail(String email) {
        driver.findElement(emailField).clear();
        driver.findElement(emailField).sendKeys(email);
    }

    /**
     * 往密码文本框输入密码 
     * @param pwd 密码
     */
    public void sendKeysPWD(String pwd) {
        driver.findElement(pwdFiled).clear();
        driver.findElement(pwdFiled).sendKeys(pwd);
    }

}

这里我们只把邮件输入框和密码输入框的操作进行封装,当然如果为了便于阅读也可以把所有的元素操作进行封装取名。


操作层

我们再新建个叫LoginMail的类,用于登录逻辑封装,供业务层Case调用,实现如下:

package com.selenium.pageobjcet;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

/**
 * Created by 米阳 on 14/10/2017.
 */
public class LoginMail {
    WebDriver driver;

    public LoginMail(WebDriver driver) {
        this.driver = driver;
    }

    /**
     * 登陆
     *
     * @param emial 邮箱地址
     * @param pwd   密码
     */
    public void login(String emial, String pwd) {
        LoginPage loginPage = new LoginPage(driver);
        WebElement element = driver.findElement(LoginPage.loginFrame);
        driver.switchTo().frame(element);
        loginPage.sendKeysEmail(emial);
        loginPage.sendKeysPWD(pwd);
        driver.findElement(LoginPage.loginBtn).click();
    }
}

业务层

最后我们来看下业务层的封装,也就是我们真正Case的编写:

package com.selenium.pageobjcet;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import java.util.concurrent.TimeUnit;

/**
 * Created by 米阳 on 14/10/2017.
 */
public class LoginTest {
    WebDriver driver;

    @BeforeClass
    public void openChrome() {
        System.setProperty("webdriver.chrome.driver", "./drivers/chromedriver.exe");
        driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    }

    @Test
    public void testLogin2() {
        driver.get("http://mail.163.com/");
        LoginMail loginMail = new LoginMail(driver);
        loginMail.login("meyoungtester", "meyoung123");
    }

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

}


小结

经过我们对登陆功能的改装,采用了PageObject思想后,假设以后要是登录页面的A元素变更,我们就不需要在工程里面到处找用到这个A元素的Case去修改他们的定位方式,我们只需要打开我们的LoginPage,找到A元素的定位方式,进行修改,则整个工程用到A元素定位的就自然而然的修改了。同样如果哪天登录流程变更了,例如登录过程必须输入验证码,那么我们也不需要把所有Case涉及到登录的都找出来,插入输入验证码过程,只需要在先在LoginPage里面登陆验证码的定位方式,接着加入打开LoginMail,在登录逻辑里面加入我们的验证码输入步骤,则用到登录逻辑的所有Case则不需要其他维护。


PageObject 的优点

一张图差不多对PO思想引入的前后对比。PO思想对界面交互细节进行了封装,这样可以使我们的自动化测试脚本案例更关注业务,而非界面细节,提高了测试案例的可读性。

image.png

PageFactory

PageFactory 整体思想同于PageObject思想,只是表象显示上不太一样,它通过注解的方式来定位元素对象,例如:

对象库层:

    @FindBy(id = "kw")
    public static WebElement emailName;

Case使用:

    @Test
    public void test(){
        driver.get("https://www.baidu.com");
        // 初始化 LoginPage
        PageFactory.initElements(driver ,LoginPage.class);
        LoginPage.emailName.sendKeys("Test");
    }

PageObject VS PageFactor

WebDriver 提供了这两种元素对象管理的思想,总的来说没有谁好谁坏,看个人习惯,实际工程也可以两者结合使用。就个人而言更习惯PageObject思想,但PageFactor也不错,通过注解方式代码看起来更加简洁。

如果文章对您有帮助,请赞赏支持!


欢迎关注个人公众号:


个人公众号
上一篇下一篇

猜你喜欢

热点阅读