设计selenium测试的页面对象结构。继承WebElement导致问题

时间:2014-07-26 09:22:22

标签: java selenium selenium-webdriver webdriver

我试图设计一些页面对象,但整体设计存在一些问题。

我知道测试中的一个常见问题是确定元素是否存在,解决方案是使用try / catch或使用findElements(...)并断言结果列表的大小是否为0。 / p>

我想在所有测试中避免这些尝试/捕获。是否可以使用继承在超类中使用try / catch,使测试更清晰?如果元素不存在,我希望返回null的方法,那么我可以在测试中断言NotNull(...)。

这是我当前解决方案中来自页面对象的方法:

public WebElement getRegisterLink(){
    List<WebElement> list = driver.findElements(By.linktext("Register"));
    if(list.size() == 0){
        return null;
    }
        return list.get(0);
}

这个问题是有很多类似的重复代码。我的getLoginButton(),getSomePageLink()等看起来都一样。

这是我有一个想法......

public abstract class MyCompanyElement implements WebElement{

WebElement element;

public MyCompanyElement(WebElement element){
    this.element = element;
}

@Override
public void clear() {
    element.clear();
}

@Override
public void click() {
    element.click();
}

@Override
public MyCompanyElement findElement(By arg0) {      
    try{
        MyCompanyElement e = (MyCompanyElement) element.findElement(arg0);
        return e;
    } catch (NoSuchElementException ex){
        return null;
    }

}

@Override
public List<MyCompanyElement> findElements(By arg0) {       
    List<MyCompanyElement> list = new ArrayList<MyCompanyElement>();
    for(WebElement e : element.findElements(arg0)){
        list.add((MyCompanyElement) e);
    }
    return list;
}

//Rest of the methods here which just call the methods of element
}

然后我有一个BasePage类,所有页面对象都将扩展。

public abstract class BasePage {

MyCompanyElement element;

public BasePage(WebDriver driver){
    element = (MyCompanyElement) driver.findElement(By.tagName("html"));        
}

//More methods here

}

然后页面对象具有getLoginButton(),getRegisterLink()等方法,它们返回MyCompanyElement而不是WebElement。 (基页包含所有网页上存在的元素,例如页眉和页脚)。

我的测试可能看起来像:

Homepage homepage = new Homepage(driver);
homepage.getLoginButton().click();

如果我想检查一个元素是否存在,那么......

assertNotNull(homepage.getRegisterLink());

上述解决方案的问题是:

  • 在MyCompanyElement中,findElement()可以返回MyCompanyElement。但编译器并不喜欢我在findElements()中返回MyCompanyElement列表。有解决方法吗?
  • 任何可以解决问题的其他想法?

由于

1 个答案:

答案 0 :(得分:2)

你说有点矫枉过正了。您无需创建自己的WebElement版本。

你应该做的是,将一个方法放入接受给定By的基类中,例如:

public WebElement getFirstMatchingElement(By by)
{
    List<WebElement> list = driver.findElements(by);
    if(list.size() == 0) {
        return null;
    }
    return list.get(0);
}

它足够通用,能够像这样调用它......

public WebElement getRegisterLink() {
    return getFirstMatchingElement(By.linktext("Register"));
}

并且喜欢......

public WebElement getLoginButton() {
    return getFirstMatchingElement(By.id("loginButton"));
}

这可以通过将代码抽象到另一种方法来解决您的问题,这意味着您的调用者(即您实际上找到元素的位置)更清晰,更简单,并且不需要&# 34;知&#34;关于所有&#34;列出东西&#34;。