Thread.sleep可以工作,但是隐式等待,webdriverwait和流畅的等待不行吗? [英] Thread.sleep works but implicit wait, webdriverwait and fluent wait does not?

查看:146
本文介绍了Thread.sleep可以工作,但是隐式等待,webdriverwait和流畅的等待不行吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

driver.findElement(By.xpath(sOptionPath)).click();  //this option button changes contents of page   
Thread.sleep(4000);
WebElement combo=driver.findElement(By.xpath(sXpath));
Select dropdownvalue = new Select(combo);
        dropdownvalue.selectByVisibleText(sText);

上面的代码可以正常工作,但是如果我使用wait而不是thread.sleep,则会收到StaleElementReferenceException异常. 这是我使用的流利的等待时间:

This above code works fine but if I use wait instead of thread.sleep I get StaleElementReferenceException exception. This is the Fluent wait I used :

    Wait<WebDriver> newwait=new FluentWait<WebDriver>(driver).withTimeout(10, TimeUnit.SECONDS).pollingEvery(1, TimeUnit.SECONDS).ignoring(StaleElementReferenceException.class);

        WebElement combo=newwait.until(new ExpectedCondition<WebElement>(){
            @Override
            public WebElement apply(WebDriver driver) {
                return driver.findElement(By.xpath(sXpath));
            }

        });

这会找到组合框,但是再次对组合框执行任何操作都会导致NoSuchElement或statestate异常.所以我也尝试过从组合框选择值:

this finds the combobox, but performing any operation on combobox again gives NoSuchElement or statestate exception. SO I also tried this to select value from combobox :

    Wait<WebElement> elwait=new FluentWait<WebElement>(combo).withTimeout(10, TimeUnit.SECONDS).pollingEvery(1, TimeUnit.SECONDS).ignoring(StaleElementReferenceException.class,NoSuchElementException.class);

        Boolean a=elwait.until(new Function<WebElement,Boolean>(){
            @Override
            public Boolean apply(WebElement arg0) {
                Select dropdownvalue = new Select(arg0);
                dropdownvalue.selectByVisibleText(sText);
                return true;
            }

        });

此超时并且不起作用!

我如何使它工作,为什么它不工作,thread.sleep工作.以及为什么使用Thread.sleep是一种不好的做法?

How can I make this work and why is it not working and thread.sleep working. And why using Thread.sleep a bad practice ?

推荐答案

我会使用ExpectedCondtions类中的某些现有检查来尝试验证返回给"combo"的对象是否陈旧.

I would try to validate that the object I'm returning to 'combo' is not stale using some of the existing checks from ExpectedCondtions class.

   Wait<WebDriver> newwait=new FluentWait<WebDriver>(driver).withTimeout(10, TimeUnit.SECONDS).pollingEvery(1, TimeUnit.SECONDS).ignoring(StaleElementReferenceException.class);

        WebElement combo=newwait.until(new ExpectedCondition<WebElement>(){
            @Override
            public WebElement apply(WebDriver driver) {
                WebElement found = driver.findElement(By.xpath(sXpath));
                if (ExpectedConditions.stalenessOf(found).apply(driver)) {
                    return null;
                }
                return found;
            }

        });

我正在使用2.47.2版本,当从委托函数返回null时,FluentWait似乎可以重试,因此,如果您否则会收到StaleElementException,我希望可以重试.

I am working off of version 2.47.2, and the FluentWait appears to retry when null is returned from the delegate Function, so I would expect this to retry if you would otherwise get the StaleElementException.

 public <V> V until(Function<? super T, V> isTrue) {
    long end = clock.laterBy(timeout.in(MILLISECONDS));
    Throwable lastException = null;
    while (true) {
      try {
        V value = isTrue.apply(input);
        if (value != null && Boolean.class.equals(value.getClass())) {
          if (Boolean.TRUE.equals(value)) {
            return value;
          }
        } else if (value != null) {
          return value;
        }
      } catch (Throwable e) {
        lastException = propagateIfNotIngored(e);
      }

      // Check the timeout after evaluating the function to ensure conditions
      // with a zero timeout can succeed.
      if (!clock.isNowBefore(end)) {
        String toAppend = message == null ?
            " waiting for " + isTrue.toString() : ": " + message;

        String timeoutMessage = String.format("Timed out after %d seconds%s",
            timeout.in(SECONDS), toAppend);
        throw timeoutException(timeoutMessage, lastException);
      }

      try {
        sleeper.sleep(interval);
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new WebDriverException(e);
      }
    }

我在一项测试中看到了类似的内容,花了我一段时间,但最终得出的结论是,在我的情况下,这是WebDriver配置中的隐式等待与显式等待时间之间的竞争条件.我还没有做过可以证明这种情况的测试,但这是我目前的理论……

睡眠

I had seen something similar in one of my tests, and it took me a while but I finally came to the conclusion that in my case it was a race condition between the implicit wait in the WebDriver configuration and the explicit wait time. I've not made a test that proves this case yet, but here's my current theory...

SLEEP

  1. 执行任务以刷新dom
  2. 睡眠-在dom刷新期间
  3. 从刷新dom重新请求对象
  4. 测试将按预期进行.

显式等待< =隐式等待

  1. 执行任务以刷新dom
  2. 显式等待触发器(10秒),抓住dom并尝试获取元素(隐式等待30秒)
  3. Dom刷新
  4. 显式等待在10秒后结束.它仅尝试一次针对原始DOM来解析对象
  5. 测试失败

显式等待>隐式等待

  1. 执行任务以刷新dom
  2. 显式等待触发器(30秒),抓住dom并尝试获取元素(隐式等待10秒)
  3. Dom刷新
  4. 10秒后,第一个请求失败,dom刷新
  5. 显式等待会尝试获取元素和SUCCEEDS
  6. 测试继续.

根据这个假设进行工作,我最近没有看到这个问题.我使隐式等待值可供我的测试访问,现在我可以根据要执行的重试次数来计算时间范围.

Working off of that assumption I've not seen this problem recently. I made the Implicit wait value accessible to my test and I now have something calculate the timeframe based on the amount of retries I want to perform.

private final WebElement explicitWait(int retries, Predicate<Boolean> test) {
        WebDriverWait wait = new WebDriverWait(driver, retries * getImplicitWait());
        return wait.until(test);
}

对于Thread.sleep的使用和可靠性,我完全同意Vinoth的观点,它不可靠,并且如果在大量测试中经常发生,可能会很浪费.最好有一种机制,该机制可以尽快响应并考虑类型正确且有意义的异常.

I completely agree with Vinoth about the use and reliability of Thread.sleep, it's unreliable and can be wasteful if it occurs too often in a large suite of tests. It's better to have a mechanism that can respond as quickly as possible and account for well-typed and meaningful exceptions.

好运.

这篇关于Thread.sleep可以工作,但是隐式等待,webdriverwait和流畅的等待不行吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆