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

到这节课为止我们已经基本上把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也不错,通过注解方式代码看起来更加简洁。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,408评论 4 371
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,690评论 2 307
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 112,036评论 0 255
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,726评论 0 221
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,123评论 3 296
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,037评论 1 225
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,178评论 2 318
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,964评论 0 213
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,703评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,863评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,333评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,658评论 3 263
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,374评论 3 244
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,195评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,988评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,167评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,970评论 2 279