避免Selenium中出现'StaleElementReferenceException”错误的方法
P粉920835423
P粉920835423 2023-08-21 17:47:18
0
2
619
<p>我正在使用Java实现很多Selenium测试 - 有时候,我的测试由于<code>StaleElementReferenceException</code>而失败。</p> <p>你能提供一些使测试更稳定的方法吗?</p>
P粉920835423
P粉920835423

全部回复(2)
P粉899950720

我曾经遇到这个问题,但是不知道的是,页面上运行了BackboneJS,并且替换了我试图点击的元素。我的代码如下。

driver.findElement(By.id("checkoutLink")).click();

这当然在功能上与下面的代码相同。

WebElement checkoutLink = driver.findElement(By.id("checkoutLink"));
checkoutLink.click();

偶尔会发生的情况是,在查找和点击之间,javascript会替换checkoutLink元素,即。

WebElement checkoutLink = driver.findElement(By.id("checkoutLink"));
// javascript替换了checkoutLink
checkoutLink.click();

这就导致在尝试点击链接时出现StaleElementReferenceException异常。我找不到任何可靠的方法告诉WebDriver等待javascript运行完毕,所以这是我最终解决的方法。

new WebDriverWait(driver, timeout)
    .ignoring(StaleElementReferenceException.class)
    .until(new Predicate<WebDriver>() {
        @Override
        public boolean apply(@Nullable WebDriver driver) {
            driver.findElement(By.id("checkoutLink")).click();
            return true;
        }
    });

这段代码将不断尝试点击链接,忽略StaleElementReferenceException异常,直到点击成功或达到超时时间。我喜欢这个解决方案,因为它省去了编写重试逻辑的麻烦,并且只使用了WebDriver的内置构造。

P粉343141633

如果页面上正在发生的DOM操作暂时导致元素无法访问,就会发生这种情况。为了应对这些情况,您可以在循环中尝试多次访问元素,直到最后抛出异常。

尝试使用darrelgrainger.blogspot.com上的这个优秀解决方案:

public boolean retryingFindClick(By by) {
    boolean result = false;
    int attempts = 0;
    while(attempts < 2) {
        try {
            driver.findElement(by).click();
            result = true;
            break;
        } catch(StaleElementException e) {
        }
        attempts++;
    }
    return result;
}
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板