一、在实现自动化过程中,会有很多重复的代码,我们在维护代码时会很困难,如果想解决这个问题,我们就需要使用PageObjectModel(页面对象模型)的方式来进行自动化代码的书写。

二、案例演示

以该网站的机票预订操作为例:https://www.expedia.com/?siteid=100001&langid=2052&currency=CNY

1、首先我们在eclipse中创建2个包,pageclasses和pomtestcase,然后在pageclasses中创建一个用于存放单个元素的类SearchPage,在pomtestcase中创建一个类用于调用创建好的元素,这样就能够把页面元素和测试的用例代码分开存放,便于维护和调用。

2、在SearchPage类中将查找元素直接封装到方法中

package pageclasses;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement; public class SearchPage { // 首先声明一个WebElement类型的变量
public static WebElement element = null ; // 加元素封装到方法中 /**
* 返回"机票按钮"元素
* @param driver
* @return
*/
public static WebElement ticketButton(WebDriver driver) {
element = driver.findElement(By.id("tab-flight-tab-hp"));
return element;
} /**
* 返回"出发文本框"元素
* @param driver
* @return
*/
public static WebElement startText(WebDriver driver) {
element = driver.findElement(By.xpath("//input[@id='flight-origin-hp-flight']"));
return element;
} /**
* 返回"飞往文本框"元素
* @param driver
* @return
*/
public static WebElement endText(WebDriver driver) {
element = driver.findElement(By.xpath("//input[@id='flight-destination-hp-flight']"));
return element;
} /**
* 返回"出发日期框"元素
* @param driver
* @return
*/
public static WebElement startData(WebDriver driver) {
element = driver.findElement(By.xpath("//input[@id='flight-departing-hp-flight']"));
return element;
} /**
* 返回"返回日期框"元素
* @param driver
* @return
*/
public static WebElement returnData(WebDriver driver) {
element = driver.findElement(By.xpath("//input[@id='flight-returning-hp-flight']"));
return element;
} /**
* 返回"点击登录"元素
* @param driver
* @return
*/
public static WebElement searchButton(WebDriver driver) {
element = driver.findElement(By.xpath("//div[@class='cols-nested ab25184-submit']//button[@class='btn-primary btn-action gcw-submit']"));
return element;
}
}

元素封装好以后,在测试类中可以直接被多出重复调用,但前端代码路径发生变化,那么就只需要修改该类中相对应的元素路径即可,测试类中调用到该元素的路径也一并进行了修改,提高了我们对自动化代码维护时的工作效率。

3、在PageObjectModel类中直接调用,这样就简化了测试类中的代码量

 package pomtestcase;

 import static org.junit.jupiter.api.Assertions.*;

 import java.util.concurrent.TimeUnit;

 import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver; import pageclasses.SearchPage; class PageObjectModel { WebDriver driver;
String url; @BeforeEach
void setUp() throws Exception {
driver = new ChromeDriver();
url = "https://www.expedia.com/?siteid=100001&langid=2052&currency=CNY";
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get(url);
} @Test
void test() throws InterruptedException {
// 调用封装了元素的SearchPage类中的“机票”按钮元素
SearchPage.ticketButton(driver).click();
Thread.sleep(1000);
// 调用封装了元素的SearchPage类中的“出发”输入框元素
SearchPage.startText(driver).sendKeys("长沙, 中国 (CSX-黄花国际机场)");
Thread.sleep(1000);
// 调用封装了元素的SearchPage类中的“返回”输入框元素
SearchPage.endText(driver).sendKeys("上海, 中国 (PVG-浦东国际机场)");
// 调用封装了元素的SearchPage类中的“出发”日期输入框元素
SearchPage.startData(driver).sendKeys("2019/07/06");
// 调用封装了元素的SearchPage类中的“返回”日期输入框元素
SearchPage.returnData(driver).sendKeys("2019/07/07");
// 调用封装了元素的SearchPage类中的“搜索”按钮元素
SearchPage.searchButton(driver).click();
} @AfterEach
void tearDown() throws Exception {
Thread.sleep(2000);
driver.quit();
}
}

三、在“案例演示”中我们只封装了查找元素的方法,但为了调用方便,我们可以将输入动作或者点击动作一并进行封装,进一步简化测试类中的代码量

将“出发地”文本框元素输入进行封装:

封装后调用:

如果有不明白的小伙伴可以加群“555191854”问我,群里都是软件行业的小伙伴相互一起学习。

内容具有连惯性,未标注的地方可以看前面的博客,这是一整套关于ava+selenium自动化的内容,从java基础开始。

欢迎关注,转载请注明来源。

章节十五、2-PageObjectModel的更多相关文章

  1. 章节十五、5-记录日志---Log4j

    一.为什么要用Log4j记录日志? 日志记录对于任何应用程序都非常重要. 它可以帮助我们快速调试代码,通过收集代码执行的信息让代码容易维护. 二.Log4j 是什么? Apache为Java提供的日志 ...

  2. 章节十五、3-对象仓库、Page Factory实例应用

    一.如何创建对象仓库 package pageclasses; import org.openqa.selenium.WebDriver; import org.openqa.selenium.Web ...

  3. 章节十五、6-log4 2-用默认的配置

    一.实例演示 package log4jtutorial; import org.apache.logging.log4j.LogManager; import org.apache.logging. ...

  4. 章节十五、7- 配置文件-Console Logging

    一.创建xml文件 1.创建xml文件 在项目中我们需要专门建一个文件夹来放xml文件或者是其它文件. 2.然后对文件夹进行命名 3.选择new  其它 4.选择XML File 5.给xml文件命名 ...

  5. 章节十五、8-配置文件File Logging

    一.如何将log输出到文件中? 1.配置xml文件 <?xml version="1.0" encoding="UTF-8"?> <Confi ...

  6. 章节十五、9-自定义Loggers

    一.如何给不同的包设置不同的日志级别? 1.针对不同的包来记录不同级别的日志信息 2.在日志xml配置文件中加入配置信息(红色标注) <?xml version="1.0" ...

  7. NeHe OpenGL教程 第三十五课:播放AVI

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  8. WCF技术剖析之二十五: 元数据(Metadata)架构体系全景展现[元数据描述篇]

    原文:WCF技术剖析之二十五: 元数据(Metadata)架构体系全景展现[元数据描述篇] 在[WS标准篇]中我花了很大的篇幅介绍了WS-MEX以及与它相关的WS规范:WS-Policy.WS-Tra ...

  9. thinkphp URL规则、URL伪静态、URL路由、URL重写、URL生成(十五)

    原文:thinkphp URL规则.URL伪静态.URL路由.URL重写.URL生成(十五) 本章节:详细介绍thinkphp URL规则.URL伪静态.URL路由.URL重写.URL生成 一.URL ...

随机推荐

  1. (入门SpringBoot)SpringBoot项目创建基本配置(二)

    SpringBoot的环境搭建和基本开发:1.环境开发就不说了,一个程序员的基本功:2.基本开发-使用自定义的配置:2.1.配置文件.properties和yml文件.2.2.SpringBoot配置 ...

  2. redis 进程使用root用户启动 -- 整改方案

    最近内部风险整改, 各种进程使用root身份进行启动不符合要求, 于是各路神仙各施其法,为的就是让 某进程不以root 启动: 先以 redis 为例: 原有进程如下: #超一流标准的执行文件位置及配 ...

  3. Linux学习(五)远程登录

    Linux一般作为服务器使用,而服务器一般放在机房,你不可能在机房操作你的Linux服务器. 这时我们就需要远程登录到Linux服务器来管理维护系统. Linux系统中是通过ssh服务实现的远程登录功 ...

  4. TeamyinyinFish->鱼嘤嘤小分队软件工程beta迭代作业

    Github项目的链接 github工作组链接 github后台部分项目代码,issue提交在这个项目 github小程序前端部分项目代码链接 scrum会议时间 链接 第十一周 十一周博客 第十二周 ...

  5. Appium自动化测试之微信h5元素识别和代码实战

    总会有人问微信的自动化测试怎么做.其实我不太明白,为啥你要对ta做自动化测试啊,除非你们公司产品是基于微信做的开发否则没必要.即使一个公众号我也觉得没必要做自动化测试,基本功能点下没问题就可以了,毕竟 ...

  6. IntelliJ IDEA 快捷键(七)

    /*方法参数提示*/ ctrl + p /*折叠代码/展开代码*/ ctrl + - / ctrl + + /*快速查找和打开最近使用过的文件*/ ctrl + E /*自动代码片*/ ctrl + ...

  7. 补充: canal

    1. 作用: 同步mysql:做拉链表:更新redis 某些情况无法从日志中获取信息,而又无法利用sqoop等ETL工具对数据实时的监控 2. canal的工作原理:                 ...

  8. Codeforces Round #596 (Div. 2, based on Technocup 2020 Elimination Round 2) B. TV Subscriptions 尺取法

    B2. TV Subscriptions (Hard Version) The only difference between easy and hard versions is constraint ...

  9. 物联网架构成长之路(35)-利用Netty解析物联网自定义协议

    一.前言 前面博客大部分介绍了基于EMQ中间件,通信协议使用的是MQTT,而传输的数据为纯文本数据,采用JSON格式.这种方式,大部分一看就知道是熟悉Web开发.软件开发的人喜欢用的方式.由于我也是做 ...

  10. multer 文件后缀名

    我的代码是这样写的. var storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, 'uplo ...