TestNG Java Selenium。除了Thread.sleep(),还有哪些替代品?

3

根据我看到的一些文章,使用Thread.sleep()似乎是不受欢迎的。在我的测试类中,我经常使用它来等待某些内容加载完成。我曾试图使用这种方法来告诉我何时加载完成,但没有帮助。它不是一种可靠的方法。

try {
        return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("loaded")
                || ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
    } catch (Exception e) {
        System.err.println(thisClass + " Exception caught: " + e.getMessage());
    }

我可以使用哪些替代方法?

这个解决方案有效:

  1. Calling function:

    String className = "gwt-Button form-control btn back-button ripple-container";
    String textToFind = "back-button-icon";
    String htmlElement = "button";
    boolean isReady = Common.FluentWait(driver, 60, className, textToFind, htmlElement);
    
  2. That function:

    public static boolean FluentWait(WebDriver driver, int timeOut, String className, String textToFind,
        String htmlElement) {
    // Waiting timeOut seconds for an element to be present on the page, checking
    // for its presence once every 5 seconds.
    Common.myPrint(thisClass + " FluentWait. ");
    Wait<WebDriver> wait = new FluentWait<WebDriver>(driver).withTimeout(timeOut, TimeUnit.SECONDS)
            .pollingEvery(5, TimeUnit.SECONDS).ignoring(NoSuchElementException.class);
    
    WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
        public WebElement apply(WebDriver driver) {
            Common.myPrint(thisClass + " run returnWebElement. ");
            return returnWebElement(className, textToFind, htmlElement, driver);
        }
    });
    
    if (foo != null) {
        return true;
    }
    return false;
    

    }

我调用的函数是:

public static WebElement returnWebElement(String className, String textToFind, String htmlElement,
        WebDriver driver) {

    List<WebElement> elements = Common.findElementsUsingHtmlXpathClass(driver, htmlElement, className);

    Common.myPrint(thisClass + " elements count: " + elements.size());
    String text = "";
    for (WebElement element : elements) {
        // select an element
        if (element.isDisplayed()) {
            text = element.getAttribute("innerHTML");
            if (text != "") {
                text = text.trim();
                if (text.contains(textToFind)) {
                    Common.myPrint(thisClass + " innerHTML: " + text);
                    Common.myPrint(thisClass + " returning element found. ");
                    return element;
                }
            }
        }
    }
    Common.myPrint(thisClass + " element not found. ");
    return null;
}
3个回答

4

您可以使用FluentWait

每个FluentWait实例都定义了等待条件的最长时间和检查条件的频率。此外,用户可以配置等待在等待过程中忽略特定类型的异常,例如在页面上搜索元素时发生NoSuchElementException异常。

/* 
code snippet will Wait 30 seconds for 
an element to be present on the page and check for its 
presence once every 5 seconds.
*/
Wait wait = new FluentWait(driver)
    .withTimeout(30, SECONDS)
    .pollingEvery(5, SECONDS)
    .ignoring(NoSuchElementException.class);

WebElement foo = wait.until(new Function() {
    public WebElement apply(WebDriver driver) {
        return driver.findElement(By.id("foo"));
    }
});

还有另一种等待方式也可用


有趣,但是@Roushan在哪里定义等待的最长时间? - Steve Staple
在这里,您可以指定.withTimeout(30, SECONDS),并且这是pollingEvery(5, SECONDS)的间隔,每5秒钟它将检查一次。 - Roushan
在99%的情况下,真的没有必要使用FluentWaitWebDriverWait完全可以胜任。只有当您需要自定义等待的所有方面时,才需要使用FluentWait,而大多数人只需要等待X秒钟以使某些条件为真,例如等待元素可点击,可见等。 - JeffC

3

虽然我发现另一种方法与Thread.sleep()非常相似,但我正在寻找另一种等待方式,因为Selenium的隐式等待和显式等待对我来说等待时间不够长。

我使用的替代方法:

TimeUnit.SECONDS.sleep(int timeUnit)

这提供了与Thread.sleep()相同的功能。希望这可以帮助到您。


正如@SteveStaple所提到的,实现sleep()方法是一种代码异味。根据文档,这本质上与Thread.sleep()相同。 如果Selenium等待的时间不够长,我非常确定你的问题是等待条件而不是Selenium。 - JDelorean
我一开始以为这只是另一种实现Thread.sleep()的方式,谢谢你澄清了我的疑惑。 - JASmith

1

您的代码只会尝试等待页面加载,而不是等待特定元素等加载完成。这对于静态HTML页面来说可以正常工作,但一旦开始添加动态部分到页面(使用AJAX等),它将无法实现您想要的效果。

您可以使用WebDriverWait。有关更多信息,请参见文档

简单的示例:

// create an instance that can be reused
WebDriverWait wait = new WebDriverWait(driver, 10);
// wait for an element to be clickable and store the return
WebElement button = wait.until(ExpectedConditions.elementToBeClickable(By.id("someId"));
// click the returned button
button.click();

有许多标准条件由ExpectedConditions提供。有关更多信息,请参见文档


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接