我对 selenium webdriver 很陌生,我正在使用 2.31 版本、testng 6.8 和 IE 8 上的防火测试。我正在这个方案中编写我的测试: 我有测试类,其中有带有 testng @Test 注释的方法。它看起来像这样:
@Test(description="click Save Button ", dependsOnMethods = { "edit form" })
public void clickSaveButton(ITestContext context) {
page.clickSaveButton(driver);
}
然后,如您所见,我有一个页面类,用于存储元素 id、xpath 等。它看起来像这样:
public void clickSaveButton(WebDriver driver){
Configuration.clickfoundElement(By.id(conf.get("saveButton")), driver);
}
conf 是代表属性文件的对象。 最后我有配置类,我在其中做了这样的思考:
public static void clickfoundElement(By by, WebDriver driver){
int attempts = 0;
while(attempts < 10) {
try {
driver.findElement(by).click();
break;
} catch(NoSuchElementException e) {
System.out.println("NoSuchElementException");
Reporter.log("NoSuchElementException<br/>");
if(attempts==9){
throw(e);
}
}
catch(StaleElementReferenceException e) {
System.out.println("StaleElementReferenceException");
Reporter.log("StaleElementReferenceException<br/>");
if(attempts==9){
throw(e);
}
}}
这可以防止我出现 NoSuchElementException 和 StaleElementReferenceException 并且工作得很好。
我的第一个问题是这种方法是否正确? 第二个也是最重要的问题是我不时遇到以下问题:
Testng 说“clickSaveButton”(在最终报告中)已通过,但实际上 clickSaveButton 操作并未发生(我可以看到它在测试期间监视我的浏览器)。在下一个测试结束时,我有“NoSuchElementException”(特别是当下一个测试不是关于单击某些内容而只是从 html 组件获取文本时)。当然,发生这个 NoSuchElementException 是因为确实没有我要查找的元素(因为最后的测试操作没有发生,所以我仍然在上一个站点,没有这个元素)你能告诉我为什么会发生这种情况吗(重要的是并不总是但只是有时)以及如何预防?
提前致谢。
最佳答案
我建议您使用显式等待来等待元素可见。这是通过 WebDriverWait 完成的,这会更改您的代码:
public void clickSaveButton(WebDriver driver){
Configuration.clickfoundElement(By.id(conf.get("saveButton")), driver);
}
对此:
public void clickSaveButton(WebDriver driver) {
WebDriverWait doWait = new WebDriverWait(driver, 15 , 100);
WebElement elementToClick = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(conf.get("saveButton"))));
elementToClick.click();
}
它还完全摆脱了 clickfoundElement() 方法。这不会阻止 StaleElementExceptions 的发生。 StaleElementException 是由于 DOM 被修改以及您想要与之交互的元素被销毁然后重新创建而引起的。
为了避免 StaleElementExceptions,您有几个选择:
- 每次使用时,始终使用定位器找到该元素。
- 使用 PageFactory 类进行支持。
我个人在所有测试代码中使用 PageFactories,一个基本示例如下所示:
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
import org.openqa.selenium.support.PageFactory;
public class LoginExample {
@FindBy(how = How.ID, using = "username")
private WebElement usernameField;
@FindBy(how = How.ID, using = "password")
private WebElement passwordField;
@FindBy(how = How.ID, using = "login")
private WebElement submitButton;
public LoginExample(WebDriver driver) {
PageFactory.initElements(driver, this);
}
public void enterCredentialsAndSubmitForm(String username, String password) {
usernameField.clear();
usernameField.sendKeys(username);
passwordField.clear();
passwordField.sendKeys(password);
submitButton.click();
}
}
@FindBy 注释有效地创建了一个代理 WebElement,每次使用此 WebElement 时,注释中指定的定位器将用于再次查找它,因此不会再出现 StaleElementException 错误(除非您很不幸,元素在这对中发生了更改) Selenium 找到它然后对其执行操作之间的毫秒数)。
在上面的示例中,我通过在构造函数中初始化页面工厂来进行欺骗,您不必这样做,但我发现这通常是一种很好且简单的方法。
有关页面工厂的更多信息,请查看 Selenium Wiki .
关于java - 测试通过,但操作没有发生 selenium webdriver + testng,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15406655/