【问题标题】:Selenium Webdriver: best practice to handle a NoSuchElementExceptionSelenium Webdriver:处理 NoSuchElementException 的最佳实践
【发布时间】:2014-05-11 22:28:44
【问题描述】:

经过大量搜索和阅读,我仍然不清楚使用 Webdriver 处理失败断言的最佳方法。我会认为这是一个常见的核心功能。我想做的就是:

  • 寻找元素
  • 如果有的话 - 告诉我
  • 如果不在场 - 告诉我

我想向非技术人员展示结果,因此让它抛出带有完整堆栈跟踪的“NoSuchElementExceptions”是没有帮助的。我只是想要一个好消息。

我的测试:

@Test
public void isMyElementPresent(){
  //  WebElement myElement driver.findElement(By.cssSelector("#myElement"));
    if(driver.findElement(By.cssSelector("#myElement"))!=null){
        System.out.println("My element was found on the page");
    }else{
            System.out.println("My Element was not found on the page");
        }
    }

当我强制失败时,我仍然会抛出 NoSuchElementException。我也需要尝试/捕捉吗?我是否可以在不需要 System.out.println 的情况下合并 Junit 断言和/或 Hamcrest 以生成更有意义的消息?

【问题讨论】:

    标签: java selenium-webdriver junit


    【解决方案1】:

    我也遇到过类似的情况。根据findElementfindElements API 的Javadoc,看来findElement 行为是设计使然。您应该使用findElements 检查不存在的元素。

    由于在您的情况下,WebElement 可能不存在,因此您应该改用 findElements

    我会按如下方式使用它。

    List<WebElement> elems = driver.findElements(By.cssSelector("#myElement"));
    if (elems.size == 0) {
            System.out.println("My element was not found on the page");
    } else
            System.out.println("My element was found on the page");
    }
    

    【讨论】:

    • 此解决方案的问题在于,当在 @Test 方法中运行时,即使未找到该元素,它也会在 Junit 结果中提供“通过”,因此在导出时会出现误报XML / HTML 结果。
    • @Steerpike,如果第一个条件为真,则测试失败(即 google "fail JUnit test" )。这个答案只是为了向您展示基本原理。
    • 好的 - 谢谢,我不敢相信直到现在我还没有遇到过 fail(string) 方法!
    【解决方案2】:

    你可以做一些事情来检查元素是否存在

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

    【讨论】:

    • 以这种方式使用 try catch 块是否理想?我认为@vish 的方式更好。
    • @lost: findElements 将尝试在页面上查找所有元素。因此,如果它仍然找到第一个也是唯一的元素,它将解析页面的其余部分以检查是否有更多匹配的元素。它会产生一些开销
    • 您的代码确实有效!但我相信 try catch 块并不意味着以这种方式使用。这也是我的看法。
    • @lost:我认为我更喜欢表现,而不是礼貌。这是我的意见。
    • @lost: 同样在 OPs 情况下,所需元素的最大数量为 1,所以我更喜欢 findElement
    【解决方案3】:

    如何在 try-catch 中使用 xPath,传递元素类型、属性和文本,如下所示?

    try {
        driver.FindElement(
            By.XPath(string.Format("//{0}[contains(@{1}, '{2}')]", 
            strElemType, strAttribute, strText)));
        return true;
    }
    catch (Exception) {
        return false;
    }
    

    【讨论】:

      【解决方案4】:

      即使在 try 块中运行它,它的行为也好像未处理, 当 selenium 异常发生时,两个 catch 块都不会运行。

      try {
          wait.Until(webDriver => webDriver.PageSource.Contains(waitforTitle));
          wait.Until(webDriver => webDriver.FindElement(By.Id(waitforControlName)).Displayed);
      }
      catch (OpenQA.Selenium.NoSuchElementException nse) {
          nse = nse = null;
          success = false;
      }
      catch (Exception ex) {
          ex = ex = null;
          success = false;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-08-09
        • 1970-01-01
        • 2013-08-25
        • 1970-01-01
        • 2018-01-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多