WebDriver实战之Page-Object设计模式

简介: 自动化脚本初写之际一定是只求完成功能测试,页面by.id、by.name、by.xpath满篇飞。业务逻辑代码重复率也是越来越高。慢慢的写着写着开始重构,开始封装一些方法。代码量好一些的人会在代码开始写之前开始预留一些接口来处理可以预见的一些功能扩展

自动化脚本初写之际一定是只求完成功能测试,页面by.id、by.name、by.xpath满篇飞。业务逻辑代码重复率也是越来越高。慢慢的写着写着开始重构,开始封装一些方法。代码量好一些的人会在代码开始写之前开始预留一些接口来处理可以预见的一些功能扩展。当代码封装好咯,会发现页面元素和页面逻辑是杂糅在一起页面更改一个按钮就要去代码里面找到按钮做相应的更改。那么能不能把页面元素和页面逻辑分离开来。当页面更改我就只改page类。逻辑更改就只改logic类。那么久引出了这篇文章的主题:Page-Object设计模式
我把我以前写的功能代码翻译成Page-Object模式用了大概一个星期。有两点写在前面希望对后来者有多帮助
1、page类元素可以是webelement或者By类型
使用方式是:@FindBy(id=“kw”)

        WebElement baiduinput;
        By baidubtn=By.id(“su”);

2、page类一定要提前初始化不然会报错:不能初始化page类
初始化page类不能放在junit的setup()方法、TestNG的beforemorth()
我是放在每个case里面的
我的Page-Object模式是三个没用接口的主要类,test类、page类、logic类。看名字就知道每个类分别放的是什么代码,下面贴一下代码
Page类:
//重置查询

 @FindBy(id="aReset" )
  WebElement aReset;

//查找人员
By serachpsnradio=By.cssSelector("div#divSelSearchType span");

//查找单位
By serachunitradio=By.cssSelector("div#divSelSearchType span");

//查看保存的查询
 @FindBy(id="aViewSaved" )
 WebElement seesaveconditions;

//查询指标弹框
 @FindBy(id="dlgSelectItem" )
 WebElement searchdlg;
  
//开始查询
 @FindBy(id="btnSearch" )
 WebElement startsearch;
 
//保存条件
 @FindBy(id="btnSave" )
 WebElement saveconditions;
 
 //保存条件弹框input
 @FindBy(id="txtConditionName" )
 WebElement saveconditiondlginput;

//添加查询条件  +
 @FindBy(id="liAddSearch" )
 WebElement addconditions;

 //添加查询条件   imggroup
 By addconditiondlgitemgroup=By.cssSelector("div#dlgSelectItem div#tree_selectItem.tv div.tv-tn span");
 
 //添加查询条件   imggroup
 By addconditiondlgimggroup=By.cssSelector("div#dlgSelectItem div#tree_selectItem.tv div.tv-tn img");

 //添加查询条件  itemnamespangroup
 By addconditiondlgresultnamespangroup=By.cssSelector("div.tv-chi div.tv-tn span");

//添加查询条件  勾选第二个复选框
 By addconditionsitemresult=By.cssSelector("div.spanCode span#lic_0.codeDiv span input");

Logic类:
static AdvanceSearchPageWebElement pagetemp=PageFactory.initElements(ReturnDriver.driver,AdvanceSearchPageWebElement.class);

static BaseFunLib basefunlib=new BaseFunLib();
   
/*
 * 函数功能:用户选择是查找人员 还是查找单位的功能函数 1、查找人员 2、查找单位
 */
public static void SelectSerachWay(String WayID,String AdvanceUrl) {
    ReturnDriver.driver.get(AdvanceUrl);
    WebElementList.SureWebElementByAttribute(
            pagetemp.serachpsnradio, "maindbtype",
            WayID);
}

/*
 * 函数功能:完成查询条件的配置
 * 
 * 1、点击查找人员 2、点击添加条件的 “+” 3、点击查询指标弹出框的 “+” 4、点击性别 5、点击确定
 * 6、勾选查询结果的第二个input复选框 比如:勾选性别=女的input
 */
public static void SerachSelect(String AdvanceUrl,String ItemName,String MainName) {

    SelectSerachWay("1",AdvanceUrl);
    pagetemp.addconditions.click();
    doubleclickmainname(pagetemp.addconditiondlgitemgroup,MainName);
    WebElementList.SureWebElementByText(
            pagetemp.addconditiondlgresultnamespangroup,ItemName);
    // 勾选性别=女    
    basefunlib.ClickSurebtn();
    WebElementList.SureWebElementByAttribute(pagetemp.addconditionsitemresult,
            "codeitemid", "2");

}
/*
 * 函数功能:保存查询条件
 * 
 * 1、调用函数 SerachSelect 完成查询条件的配置 2、点击开始查询按钮 3、点击保存条件按钮 4、输入条件名称 5、点击确定
 */
public static void saveserachterm(String serachName,String AdvanceUrl,String ItemName,String MainName) {
    SerachSelect(AdvanceUrl,ItemName,MainName);
    pagetemp.startsearch.click();
    pagetemp.saveconditions.click();
    basefunlib.sleep(1);
    pagetemp.saveconditiondlginput.sendKeys(
            serachName);
    basefunlib.ClickSurebtn();
}
 //double click
public static void doubleclickmainname(By locate,String mainname) {
    List<WebElement> webelementlist = ReturnDriver.driver
            .findElements(locate);
    for (WebElement webelementID : webelementlist) {

test类:
static BaseFunLib basefunlib=new BaseFunLib();
//@Parameters({ "ProjectID", "ProjectName" })

@BeforeMethod
public void beforeTestMethod() {
    ReturnDriver.driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); 
  
}


/*
 * 1、选择查找人员 2、点击主页的条件添加 “+”
 * 
 * 验证是否弹出查询指标弹出框
 */
@Test (dataProvider = "AdvanceSerach",dataProviderClass=StaticProvider.class)
public void testserachPSN(String PID,String PName,String UserName,String MainName,String ItemName,String ItemResult,String B01tName) {
     
    AdvanceSearchPageWebElement pagetemp=PageFactory.initElements(ReturnDriver.driver,AdvanceSearchPageWebElement.class);

    //初始化用列    
    loginclass.login(PID,PName,UserName);
    GetTestUrlByXmlParameter GetUrlTool=new GetTestUrlByXmlParameter(PID,PName);
    String AdvanceUrl=GetUrlTool.GetAdvanceSerachUrl();
    
    
    AdvanceSearchLogicMethod.SelectSerachWay("1",AdvanceUrl);
    pagetemp.addconditions.click();
    Assert.assertTrue(pagetemp.searchdlg.getText().contains(MainName));

}

/*
 * 1、保存查询条件 2、点击 “查看保存的查询” 3、删除刚刚保存的查询条件 验证弹出框的text是否包含刚刚保存的条件名称
 */
@Test (dataProvider = "AdvanceSerach",dataProviderClass=StaticProvider.class)
public void testserachBysex(String PID,String PName,String UserName,String MainName,String ItemName,String ItemResult,String B01tName) {
     
    AdvanceSearchPageWebElement pagetemp=PageFactory.initElements(ReturnDriver.driver,AdvanceSearchPageWebElement.class);

    //初始化用列        
    loginclass.login(PID,PName,UserName);
    GetTestUrlByXmlParameter GetUrlTool=new GetTestUrlByXmlParameter(PID,PName);
    String AdvanceUrl=GetUrlTool.GetAdvanceSerachUrl();
    
    String AdvanceSerachName=ItemName + "=" + ItemResult+ System.currentTimeMillis();
    AdvanceSearchLogicMethod.saveserachterm(AdvanceSerachName,AdvanceUrl,ItemName,MainName);
    pagetemp.seesaveconditions.click();
    Assert.assertTrue(pagetemp.seeconditionsdlg.getText()
            .contains(AdvanceSerachName));
    basefunlib.Clickdeletelink();

}
相关文章
|
14天前
|
设计模式 存储 缓存
「全网最细 + 实战源码案例」设计模式——享元模式
享元模式(Flyweight Pattern)是一种结构型设计模式,旨在减少大量相似对象的内存消耗。通过分离对象的内部状态(可共享、不变)和外部状态(依赖环境、变化),它有效减少了内存使用。适用于存在大量相似对象且需节省内存的场景。模式优点包括节省内存和提高性能,但会增加系统复杂性。实现时需将对象成员变量拆分为内在和外在状态,并通过工厂类管理享元对象。
147 83
|
10天前
|
设计模式 存储 算法
「全网最细 + 实战源码案例」设计模式——命令模式
命令模式(Command Pattern)是一种行为型设计模式,将请求封装成独立对象,从而解耦请求方与接收方。其核心结构包括:Command(命令接口)、ConcreteCommand(具体命令)、Receiver(接收者)和Invoker(调用者)。通过这种方式,命令的执行、撤销、排队等操作更易扩展和灵活。 适用场景: 1. 参数化对象以操作。 2. 操作放入队列或远程执行。 3. 实现回滚功能。 4. 解耦调用者与接收者。 优点: - 遵循单一职责和开闭原则。 - 支持命令组合和延迟执行。 - 可实现撤销、恢复功能。 缺点: - 增加复杂性和类数量。
48 14
「全网最细 + 实战源码案例」设计模式——命令模式
|
10天前
|
设计模式 存储 Java
「全网最细 + 实战源码案例」设计模式——责任链模式
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,允许将请求沿着处理者链进行发送。每个处理者可以处理请求或将其传递给下一个处理者,从而实现解耦和灵活性。其结构包括抽象处理者(Handler)、具体处理者(ConcreteHandler)和客户端(Client)。适用于不同方式处理不同种类请求、按顺序执行多个处理者、以及运行时改变处理者及其顺序的场景。典型应用包括日志处理、Java Web过滤器、权限认证等。
47 13
「全网最细 + 实战源码案例」设计模式——责任链模式
|
12天前
|
设计模式 算法 开发者
「全网最细 + 实战源码案例」设计模式——策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,用于定义一系列可替换的算法或行为,并将它们封装成独立的类。通过上下文持有策略对象,在运行时动态切换算法,提高代码的可维护性和扩展性。适用于需要动态切换算法、避免条件语句、经常扩展算法或保持算法独立性的场景。优点包括符合开闭原则、运行时切换算法、解耦上下文与策略实现、减少条件判断;缺点是增加类数量和策略切换成本。示例中通过定义抽象策略接口和具体策略类,结合上下文类实现动态算法选择。
47 8
「全网最细 + 实战源码案例」设计模式——策略模式
|
12天前
|
设计模式 SQL 算法
「全网最细 + 实战源码案例」设计模式——模板方法模式
模板方法模式是一种行为型设计模式,定义了算法的骨架并在父类中实现不变部分,将可变部分延迟到子类实现。通过这种方式,它避免了代码重复,提高了复用性和扩展性。具体步骤由抽象类定义,子类实现特定逻辑。适用于框架设计、工作流和相似算法结构的场景。优点包括代码复用和符合开闭原则,缺点是可能违反里氏替换原则且灵活性较低。
60 7
「全网最细 + 实战源码案例」设计模式——模板方法模式
|
18天前
|
设计模式 Java 开发者
「全网最细 + 实战源码案例」设计模式——适配器模式
适配器模式(Adapter Pattern)是一种结构型设计模式,通过引入适配器类将一个类的接口转换为客户端期望的另一个接口,使原本因接口不兼容而无法协作的类能够协同工作。适配器模式分为类适配器和对象适配器两种,前者通过多重继承实现,后者通过组合方式实现,更常用。该模式适用于遗留系统改造、接口转换和第三方库集成等场景,能提高代码复用性和灵活性,但也可能增加代码复杂性和性能开销。
67 28
|
14天前
|
设计模式 存储 安全
「全网最细 + 实战源码案例」设计模式——组合模式
组合模式(Composite Pattern)是一种结构型设计模式,用于将对象组合成树形结构以表示“部分-整体”的层次结构。它允许客户端以一致的方式对待单个对象和对象集合,简化了复杂结构的处理。组合模式包含三个主要组件:抽象组件(Component)、叶子节点(Leaf)和组合节点(Composite)。通过这种模式,客户端可以统一处理简单元素和复杂元素,而无需关心其内部结构。适用于需要实现树状对象结构或希望以相同方式处理简单和复杂元素的场景。优点包括支持树形结构、透明性和遵循开闭原则;缺点是可能引入不必要的复杂性和过度抽象。
72 22
|
18天前
|
设计模式 缓存 Java
「全网最细 + 实战源码案例」设计模式——代理模式
代理模式(Proxy Pattern)是一种结构型设计模式,通过代理对象控制对目标对象的访问并添加额外功能。它分为静态代理和动态代理,后者包括JDK动态代理和CGLIB动态代理。JDK动态代理基于接口反射生成代理类,而CGLIB通过继承目标类生成子类。代理模式适用于延迟初始化、访问控制、远程服务、日志记录和缓存等场景,优点是职责分离、符合开闭原则和提高安全性,缺点是增加系统复杂性。
69 25
|
16天前
|
设计模式 前端开发 数据库
「全网最细 + 实战源码案例」设计模式——桥接模式
桥接模式(Bridge Pattern)是一种结构型设计模式,通过将抽象部分与实现部分分离,使它们可以独立变化,从而降低代码耦合度,避免类爆炸,提高可扩展性。其结构包括实现类接口、具体实现类、抽象类和精确抽象类。适用于多维度扩展类、隐藏实现细节、简化庞杂类以及运行时切换实现方法的场景。优点包括高扩展性、隐藏实现细节、遵循开闭原则和单一职责原则;缺点是可能增加代码复杂度。示例中展示了不同操作系统播放不同格式视频文件的实现。
46 19
|
16天前
|
设计模式 存储
「全网最细 + 实战源码案例」设计模式——装饰者模式
装饰者模式(Decorator Pattern)是一种结构型设计模式,通过“包装”现有对象来为其添加额外功能,而无需修改原有代码。它通过创建装饰类来扩展对象的功能,而非继承。该模式由抽象构件、具体构件、抽象装饰者和具体装饰者组成,允许在运行时动态组合功能。穿衣服的例子很好地解释了装饰者模式:你可以根据需要一层层添加衣物,如毛衣、夹克和雨衣,每件衣物都扩展了基本行为,但不是你的一部分,可以随时脱掉。 优点包括灵活性、避免子类爆炸和符合开闭原则;缺点是可能增加复杂性和难以理解。适用于希望在不修改代码的情况下为对象新增行为的场景,尤其当继承难以实现或不可行时。
50 15

热门文章

最新文章