WebDriver / Read元素转换为变量并重用它们

时间:2014-01-01 08:24:30

标签: selenium

我对Webdriver(Selenium 2)有一个大问题。

在我的测试代码中,我在测试开始时找到所有元素,并对它们执行一些操作(如click(),检查属性等)。我的问题是我的页面刷新并重新加载我的元素,而Webdriver不知道再次识别元素。

我知道我可以再次找到我的元素,但在某些函数中,我不知道我的XPath / ID,而且我只得到WebElements,而不是XPath / ID。

我是否正确地说,不可能将元素读入变量并重新使用它们?

2 个答案:

答案 0 :(得分:3)

WebElement element = driver.findElement(By.id("xyz"));

上面的行将元素对象存储在element中。你当然可以将这个元素传递给其他函数,以便在那里使用它。

我们通常遵循一种称为PageObject模式的模式,我们将页面的所有对象创建为类的成员并立即实例化它们。这样我们就可以在项目的任何地方使用它们。例如,Login页面中的所有对象都将在名为LoginPage的类中创建为公共静态变量。 LoginPage类的构造函数将查找元素并存储它们。

下次你想访问LoginPage的对象时,我们按如下方式访问它们(假设你已经创建了元素userName并提交)...

LoginPage.userName.sendKeys("buddha");
LoginPage.submit.click();

然而,正如Robie所说,在页面刷新后使用先前创建的对象有可能无法访问此对象。您可以使用以下修改的方法来确保始终找到这些对象。

不是将对象创建为成员变量,而是为您可能需要使用的每个对象创建一个getmethod。

class LoginPage
{
    public static WebElement getUserName()
    {
         return driver.findElement(By.id("xyz"));
    }
}

一旦定义了LoginPage,下次要使用userName时,请使用以下语法。这样,您就不必为需要使用这些对象的函数提供定位器。

LoginPage.getUserName().sendKeys("buddha");

通过使用此方法,您可以确保始终可以访问对象。

答案 1 :(得分:1)

佛陀在以下陈述中不正确:

  

您可以多次重复使用它,但只有在ID不变的情况下才能重复使用。

正如您正确观察到的那样,如果页面重新加载,则即使原始对象仍显示在屏幕上,元素也会变得陈旧。实际上,即使URL没有改变,通过AJAX调用刷新HTML也会使对象失效。

这是Selenium的工作方式,在决定如何实现测试框架时,您必须了解这一点。

您可以存储元素,重用它们并将它们传递给函数,但要了解它们何时会变得陈旧并需要重新构建。

在我当前的项目中,我有一个非常AJAX繁重的应用程序,其中对象不断变得陈旧,因此扩展WebElement以在构造时查找并存储它的HTML Id,然后在发生陈旧元素异常时重新执行id并重新执行失败的方法。但是,这是使用Ruby实现的,并且非常特定于我的应用程序,因为我知道每个对象都有唯一的HTML Id。我不相信这种方法适用于大多数被测试的应用程序。

我还会质疑在构造中填充的公共静态变量中存储元素是否实际遵循Page Object模式。我以前从未见过以这种方式实现,并且可以看到许多潜在的陷阱。遵循页面对象模式时,延迟实例化可能是更好的方法。