【发布时间】:2018-11-09 15:43:48
【问题描述】:
在实时自动化中,我们是否在对其执行某些操作之前检查每个元素(在测试中)是否存在?
只要有findElement 语句,就有可能出现NoSuchElementException。我的问题是我们是否每次都检查元素的存在?
是否每个findElement 语句都需要被try-catch 块包围?
【问题讨论】:
标签: selenium
在实时自动化中,我们是否在对其执行某些操作之前检查每个元素(在测试中)是否存在?
只要有findElement 语句,就有可能出现NoSuchElementException。我的问题是我们是否每次都检查元素的存在?
是否每个findElement 语句都需要被try-catch 块包围?
【问题讨论】:
标签: selenium
有两种情况需要考虑:
对于第一种情况,我使用以下辅助方法:
this.waitForElement = function(locator) {
browser.wait(function() {
return browser.isElementPresent(locator);
}, testData.Timeout.TWO_MINUTES);
};
这将等待与提供的定位器匹配的元素出现的任意时间(它存在于 DOM 中)。
对于第二种情况,我使用这个辅助方法:
this.waitForElementIsVisible = function(el){
let EC = protractor.ExpectedConditions;
browser.wait(EC.visibilityOf(el), testData.Timeout.TWO_MINUTES, "Element did not become visible after 2 minutes");
};
这将WebElement作为单个参数并等待直到元素变为可见(它存在于DOM中并且不会通过css样式或其他方式隐藏)
另外,我还发现这个辅助方法对于测试表单中的错误状态很有用:
this.waitForElementIsClickable = function(el){
let EC = protractor.ExpectedConditions;
browser.wait(EC.elementToBeClickable(el), testData.Timeout.TWO_MINUTES, "Element did not become clickable after 2 minutes");
};
将WebElement 作为第一个参数并等待直到可以单击该WebElement。
注意,我正在使用量角器,并在这些 sn-ps 中引用量角器。因此,除非您也使用量角器,否则这些可能无法通过直接复制+粘贴来 100% 工作。不过应该很容易调整它们以适应您的设置。
【讨论】:
您可能会发现使用AbstractWebDriverEventListener 类特别有用。该类实现了接口WebDriverEventListener,它为WebDriver触发的事件定义了before和after钩子。
可以实现一个这样的前钩子beforeFindBy 来检查元素的存在。例如:
public void beforeFindBy(By by, WebElement element, WebDriver driver) {
// Explicit wait to check for the presence of the element using the "by" locator
}
类似地,可以实现 before 钩子 beforeClickOn 以在对该元素执行点击事件之前检查该元素是否可点击。
【讨论】:
beforeFindBy 方法中使用try-catch 块来捕获异常(例如:NoSuchElementException)。您能否为我提供一个解决方案,以在出现异常时停止该特定测试并继续下一个测试。
检查网页元素是否存在的最直接、最简单的方法是使用返回数组的 findElements()(注意复数形式),即
if (driver.findElements(By.xpath("//a")).isEmpty())
// no links exist
同样的方法可以用来检查单个元素,它不必是一个数组。返回的 .size() 为零表示没有匹配项,因此所需的元素不在 DOM 中。
有些人认为,更好的方法是将 .findElement 包装在一个方法中,该方法确实会尝试/捕获并记录/响应各种结果,例如未找到元素或陈旧元素等。
我在测试中使用这两种方法,并使用我自己的存在函数和 .findElements 逻辑,但将包装器用于其他场景。
【讨论】:
findElement 语句的每个步骤中检查元素的存在?
简短的回答:没有。 更长的答案:一种方法是等到“页面完成”指示器使用显式等待。这将表明您可以根据需要安全地找到元素。如果其中一个元素不可用,则测试将失败,表明它找不到该元素。 在测试中根据需要使用显式等待(当您期望页面/DOM 发生更改时)。
但同样,对这个问题及其答案也有一些看法。在整个过程中检查/等待元素是否存在确实需要花费运行时间,并且可能只会延长可能更快失败的测试。
【讨论】:
一一回答你的问题:
有 3 个最广泛使用的 ExpectedConditions 可以与 WebDriverWait 结合使用来验证元素的状态,如下所示:
presenceOfElementLocated(By locator) 定义如下:
public static ExpectedCondition<WebElement> presenceOfElementLocated(By locator)
Description : An expectation for checking that an element is present on the DOM of a page. This does not necessarily mean that the element is visible.
visibilityOfElementLocated(By locator) 定义如下:
public static ExpectedCondition<WebElement> visibilityOfElementLocated(By locator)
Description : An expectation for checking that an element is present on the DOM of a page and visible. Visibility means that the element is not only displayed but also has a height and width that is greater than 0.
elementToBeClickable(By locator) 定义如下:
public static ExpectedCondition<WebElement> elementToBeClickable(By locator)
Description : An expectation for checking an element is visible and enabled such that you can click it.
NoSuchElementException。这里有关于NoSuchElementExeption, selenium unable to locate element的详细讨论
Does every findElement statement need to be surrounded by try-catch block:不,并非总是如此。如果您的用例涉及处理肯定和否定两种情况,那么try-catch {}块是完美的。【讨论】:
WebDriverEventListener 接口中使用ExpectedConditions 和WebDriverWait