8

我正在测试一个仍在开发中的网站。

通常,元素的 id、类、文本或 DOM 中的位置会发生变化。然后我一直使用的定位器将不再能够找到该元素。

但是这些功能仍然可以正常运行。当没有实际回归时,我不希望几个测试失败。

因此,我没有为每个元素使用一个定位器,而是有一个定位器集合。

public static final ArrayList<By> LOGIN_ANCHOR_LOCATORS = new ArrayList<By>();

static {
     LOGIN_ANCHOR_LOCATORS.add(By.id("loginLink"));
     LOGIN_ANCHOR_LOCATORS.add(By.linkText("Login"));
     LOGIN_ANCHOR_LOCATORS.add(By.xpath("/html/body/div[5]/a"));         
}

我查找元素的方法如下所示:

public WebElement locateElement(ArrayList<By> locators){

    // create an element to return
    WebElement element = null;

    // until the desired element is found...
    while (element == null){

        // loop through the locators
        for (By locator : locators){

            // try to find by locator
            element = customWait.until(ExpectedConditions.presenceOfElementLocated(locator));

            // if not found...
            if (element == null){

                // log the failure
                logFailingLocator(locator);
            }
        }
    }
    return element;
}

它尝试使用集合中的第一个定位器查找元素,并且只有当它失败时,才尝试下一个定位器。

该集合是一个ArrayList(顺序由插入顺序定义),这意味着我for loop将按照它们添加到列表中的顺序尝试每个定位器。

我通过按特定顺序添加定位器来初始化上面的列表。id 是第一位的,因为我认为如果元素在 DOM 中的位置发生变化,但它保留了它的 id,那么这将是我最有可能找到正确元素的方式。Xpath 是最后一个,因为即使 id/class/text 发生变化,但在 DOM 中该位置仍有相同类型的元素,它可能是正确的元素,但可能不如其他定位器确定。

我正在使用忽略 NoSuchElementException 的流利等待:

// Wait 5 seconds for an element to be present on the page, checking
// for its presence once every quarter of a second.
Wait<WebDriver> customWait = new FluentWait<WebDriver>(driver)
        .withTimeout(5L, TimeUnit.SECONDS)
        .pollingEvery(250L, TimeUnit.MILLISECONDS)
        .ignoring(NoSuchElementException.class);

因此,当一个定位器失败时,它不会中断循环——它只是记录失败,然后仍然继续尝试下一个定位器。

如果所有定位器都失败了,那么元素将保持为空,测试将失败,并且更可能的原因是特性/功能的实际回归。

我会定期检查我的日志中是否有 1 或 2 个失败定位器的任何元素,同时在我的 pageObject 中更新它们,同时测试继续顺利运行。

以这种方式设置我的项目有什么优点或缺点?

4

1 回答 1

2

这是一种有趣的方法,但我担心您可能会掩盖其他问题。我更愿意与开发人员更密切地合作,以避免一开始就破坏 UI 问题。

不断变化的 ID 是动态生成的吗?如果是这种情况,请查看是否无法在 ID 上获得后缀,例如 _loginlink。您可能还必须使用从附近的静态 ID 开始的 XPath:“//div[@id='login_link_container'/a”。(从文档的根目录开始,如您的示例所示,这是一个痛苦的秘诀!:))

于 2013-06-07T16:05:19.930 回答