在Selenium中每个元素使用多个定位器的优点/缺点?

Din*_*ent 8 java testing selenium automated-tests webdriver

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

DOM中元素的id,类,文本或位置通常会发生变化.然后我一直在使用的定位器将无法再找到该元素.

但功能仍然正常运行.当没有实际的回归时,我不希望几个测试失败.

因此,我没有为每个元素设置一个定位器,而是有一组定位器.

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"));         
}
Run Code Online (Sandbox Code Playgroud)

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

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;
}
Run Code Online (Sandbox Code Playgroud)

它尝试在集合中找到具有第一个定位符的元素,并且只有在它失败时,尝试下一个定位器.

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

我通过按特定顺序添加定位器来初始化上面的列表.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);
Run Code Online (Sandbox Code Playgroud)

因此,当一个定位器失败时,它不会破坏循环 - 它只记录失败,然后继续尝试下一个定位器.

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

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

以这种方式设置项目的利弊是什么?

Jim*_*mes 2

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

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