23

我使用 Java 在 Selenium WebDriver 中编写了一些测试用例,并在网格(集线器和多个节点)上执行它们。我注意到一些测试用例由于NoSuchElementException. 避免NoSuchElementException和确保始终找到元素的最佳且稳健的方法是什么?

4

9 回答 9

32

您永远无法确定是否会找到该元素,实际上这是功能测试的目的 - 告诉您页面上是否有任何更改。但是肯定有帮助的一件事是添加等待经常导致NoSuchElementException类似的元素

WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id<locator>));
于 2013-10-23T08:50:32.943 回答
8

我完全同意上面的 Petr Mensik。你永远不能说元素是否存在。您应该清楚地了解为什么会发生这种情况。根据我的经验,我应该说它的发生是由于以下原因:

  • 1)页面仍在渲染中,您已经完成了元素搜索并且没有获得元素异常。
  • 2)第二个原因是AJAX还没有返回,你已经获取NoSuchElementException
  • 3)第三个是最明显的:元素真的不在页面上。

因此,恕我直言,使用一个函数调用处理所有这三个条件的最强大的方法是fluentWait按照 Amith003 的建议使用。

所以代码如下:

让你的元素有定位器:

String elLocXpath= "..blablabla";
WebElement myButton= fluentWait(By.xpath(elLocXpath));
myButton.click();

public WebElement fluentWait(final By locator){
        Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
                .withTimeout(30, TimeUnit.SECONDS)

                .pollingEvery(5, TimeUnit.SECONDS)

        .ignoring(org.openqa.selenium.NoSuchElementException.class);
        WebElement foo = wait.until(
                new Function<WebDriver, WebElement>() {
                    public WebElement apply(WebDriver driver) {
                        return driver.findElement(locator);
                    }
                }
        );
        return  foo;
    };

此外,如果您的目的是fluentWait()使用try{} catch{}块进行强大的代码包装。

也不要忘记

 public boolean isElementPresent(By selector)
   {

              return driver.findElements(selector).size()>0;
}

这也很有用。

因此,如果您想避免NoElement异常,请总结所有提到的内容,只需正确处理它,因为没有人可以确保页面上的元素存在。

希望现在你更清楚了。问候

于 2013-10-23T10:42:23.993 回答
4

你也可以使用FluentWait

每个FluentWait实例定义等待条件的最长时间,以及检查条件的频率。

此外,用户可以将等待配置为在等待时忽略特定类型的异常,例如NoSuchElementExceptions在页面上搜索元素时。

// Waiting 30 seconds for an element to be present on the page, checking
   // for its presence once every 5 seconds.
   Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
       .withTimeout(30, SECONDS)
       .pollingEvery(5, SECONDS)
       .ignoring(NoSuchElementException.class);

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

点击这里获取更多信息

于 2013-10-23T09:14:45.267 回答
2
public WebElement fluientWaitforElement(WebElement element, int timoutSec, int pollingSec) {

    FluentWait<WebDriver> fWait = new FluentWait<WebDriver>(driver).withTimeout(timoutSec, TimeUnit.SECONDS)
    .pollingEvery(pollingSec, TimeUnit.SECONDS)
    .ignoring(NoSuchElementException.class, TimeoutException.class);

    for (int i = 0; i < 2; i++) {
        try {
            //fWait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//*[@id='reportmanager-wrapper']/div[1]/div[2]/ul/li/span[3]/i[@data-original--title='We are processing through trillions of data events, this insight may take more than 15 minutes to complete.']")));
            fWait.until(ExpectedConditions.visibilityOf(element));
            fWait.until(ExpectedConditions.elementToBeClickable(element));
        } 
        catch (Exception e) {

            System.out.println("Element Not found trying again - " + element.toString().substring(70));
            e.printStackTrace();
        }
    }

    return element;
}
于 2016-08-19T11:27:41.323 回答
1
WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
wait.until(ExpectedConditions.elementToBeClickable(By.id<locator>));

elementToBeClickable等待元素的EnableVisible

于 2013-11-12T07:35:51.317 回答
1

当定位器(即 id/xpath/css 选择器)无法在网页上找到 Web 元素时,会发生 NoSuchElementException。

其原因可能是:

  1. 定位器不正确

  2. Web 元素在网页上不可用

    为了避免这个异常,我们可以使用 Fluent Wait。这种等待允许我们定义最大超时、轮询频率并定义要忽略的异常。

请在下面找到 Fluent wait 的示例用法:

.withTimeout(50, TimeUnit.SECONDS)
.pollingevery(3, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
于 2020-07-17T20:09:17.367 回答
0

我通常在主函数中使用这一行

public static void main(String[] args) throws ParseException {
    driver= new ChromeDriver();
    driver.manage().window().maximize();
    **driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);**

希望这可以帮助。

于 2017-02-21T00:42:41.420 回答
0

我们可以应用以下代码来删除此异常条件

  1. 通过应用 WebDriverWait,webdriver 对象等待元素的特定时间(以秒为单位)以获取其可见性。

          WebDriverWait wait = new WebDriverWait(driver, 10);       
           wait.until(ExpectedConditions.visibilityOf(link));
    
  2. 我们可以通过 Generic 方法中的 try-catch 块来处理 NoSuchElementException

     public boolean isElementPresent(By by) {
     boolean isPresent = true;
     try {
     driver.findElement(by);
     } catch (NoSuchElementException e) {
      isPresent = false;
     }
    return isPresent
    }
    

http://selenium-code.blogspot.in/2017/08/selenium-exception-nosuchelementexcepti.html

于 2017-09-15T09:54:20.870 回答
0

有时可以等待所需项目的下载。

driver.get("https://zzzzzzzzz.market/items/mirage_prime_set")

WebDriverWait(driver, 20)
       .until(
        EC.visibility_of_element_located(
          (By.XPATH, ('//div[@class="orders-row__element order__price sell_color"]')
        )))

有时您需要做一些事情以便 UI 框架加载数据。例如滚动页面

driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

然后获取必要的数据

responsetext=driver.page_source

from lxml import html
parsed_body = html.fromstring(responsetext)

obj1 = parsed_body.xpath('.//div[@class="orders-row__element order__price sell_color"]/span[1]')
print(len(obj1))
于 2019-05-02T08:01:40.700 回答