首頁  >  問答  >  主體

避免Selenium中出現「StaleElementReferenceException」錯誤的方法

<p>我正在使用Java實現很多Selenium測試 - 有時候,我的測試由於<code>StaleElementReferenceException</code>而失敗。 </p> <p>你能提供一些讓測試更穩定的方法嗎? </p>
P粉920835423P粉920835423425 天前588

全部回覆(2)我來回復

  • P粉899950720

    P粉8999507202023-08-22 15:30:51

    我曾經遇到這個問題,但是不知道的是,頁面上運行了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的內建構造。

    回覆
    0
  • P粉343141633

    P粉3431416332023-08-22 13:04:24

    如果頁面上正在發生的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;
    }

    回覆
    0
  • 取消回覆