首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WebDriver PageObjects和大量定位器

WebDriver PageObjects和大量定位器
EN

Stack Overflow用户
提问于 2014-01-20 10:42:27
回答 1查看 602关注 0票数 2

在过去的一年里,我为我的团队构建了一个非常好的WebDriver框架。相当标准:在我们的平台上,页面类通常封装了页面的全部功能(通过对象控制,根据需要使用方法),并使用一些全局方法扩展基类,在JUnit测试类中调用多个页面,典型的断言方法,yada yada。没有什么华而不实的东西--非常循规蹈矩,但非常实用和灵活。

然而,最近,我被要求使用这个框架来自动化大量具有表单的页面,这些表单可以容纳100个甚至更多的输入、选择、选项等。这让我感到非常震惊。此外,许多自定义表单控件的id随着环境的不同而变化(幸运的是,在最初的推送之后,它们在每个环境中保持不变)。不管怎样..。

让我们来看看我每天使用的一个典型的PageObject结构:

代码语言:javascript
复制
/** Constructor*/
public someConstructor(WebDriver driver){
   super(driver, pageTitle);
}

/**Locators*/
By searchBoxLocator = By.id("phSearchInput");
By searchBoxClearLocator = By.id("phSearchClearButton");
By searchButtonLocator = By.cssSelector("input[value='Search']");


/**Some Methods*/
public void selectFromTabBar(String tabName){
   driver.findElement(By.linkText(tabName)).click();
}

public static void enterInputValue(WebDriver driver, By by, String val){

   List<WebElement> elements = null;
   elements = driver.findElements(by);

   if(!elements.isEmpty()){
     driver.findElement(by)).sendKeys(val);     
   }else{
     throw new NoSuchElementException("Message");
   }
}

就像我提到的,这里没有什么异国情调,但现在我要问大家一个问题。举个例子,我不会在每个PageObject上使用传统的5-15by‘s,但是10个页面可能需要超过100个。更复杂的是,它们还将在每个环境中具有独特的值,这完全不是每个人都能掌握的,并且无法协调。因此,什么是适当的方法,我咬子弹和硬代码100“的每页,我是外部化所有的,比方说,Excel文档,并拉入所有的东西通过,我duno,JXL或任何东西,还是我硬编码的,我知道将是静态的,并把所有的东西都放在一个外部文件中吗? here...Do‘s。

归根结底,我知道没有正确的答案,但我只是好奇其他人对此的看法。现在,我已经外部化了页面的By,这些页面有如此多的表单元素,并定义了在PageObject中不会改变的控件,但感觉很笨拙。也许我太追求优雅了,但任何想法都会很奇妙。

EN

回答 1

Stack Overflow用户

发布于 2014-01-20 11:48:08

这主要是基于观点的,但很有趣的问题。

我的建议是模块化你的页面。

例如,你有一个有100个定位器的页面,但它们肯定不能是100个类似的文本框来让用户填写。(如果是这样,这里的解决方案可能是首先重新设计你的UI )

如果这100个元素属于不同的组件,比如顶部工具栏中的20个元素,列表视图中的20个元素,表单中的20个元素和底部工具栏中的20个元素。然后,您可能希望为每个组件创建不同的类。

例如,下面是一个普通的页面对象。

代码语言:javascript
复制
public class FooPage {

    private IWebDriver driver;

    public FooPage(IWebDriver driver) {
         this.driver = driver;
    }

    public IWebElement Element1 {
         get { return driver.FindElement(By.CssSelector(".something1")); }
    }

    // ...
    public IWebElement Element100 {
         get { return driver.FindElement(By.CssSelector(".something100")); }
    }

    public void AddItem(){
    }

    public void ClearList(){
    }
}

您可以将这些元素分成不同的组件,例如,FooPageTopToolbarFooPageList等。

代码语言:javascript
复制
public class FooPageTopToolbar {

    private IWebDriver driver;

    public FooPageTopToolbar(IWebDriver driver) {
         this.driver = driver;
    }

    // ...
    public IWebElement ToolbarElement10 {
         get { return driver.FindElement(By.CssSelector(".something100")); }
    }

    public void AddItem(){
    }
}

public class FooPageList {

    private IWebDriver driver;

    public FooPageList(IWebDriver driver) {
         this.driver = driver;
    }

    // ...
    public IWebElement ListElement10 {
         get { return driver.FindElement(By.CssSelector(".something100")); }
    }

    public void ClearList(){
    }
}

现在,您的FooPage将如下所示

代码语言:javascript
复制
public class FooPage {

    private IWebDriver driver;

    public FooPage(IWebDriver driver) {
         this.driver = driver;
    }

    public FooPageTopToolbar {
         get { return new FooPageTopToolbar(driver); }
    }

    // other components as well
    public FooPageList {
         get { return new FooPageList(driver); }
    }
}

注意这只是一个演示,你也可以考虑使用get inheritanceinterfacesabstraction来构建你的页面对象。例如,如果TopToolbar被许多其他页面共享,那么您只需要为所有页面提供一个类。如果不同的页面具有相似但略有不同的工具栏,则创建某种抽象工具栏类。

另外,你提到你对不同的环境有不同的定位器,在我看来最好的解决方案是在你的源代码中添加元素标识符(所谓的“标识符”,我指的是任何可识别的部分,可能是超文本标记语言id,但最常见的是用于测试的唯一class )。在这种情况下,您只需要一组UI开发人员不经常更改的测试定位器。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21225462

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档