测试通过但行动没有发生selenium webdriver + testng

我是selenium webdriver的新手,我在IE 8上使用2.31版本,testng 6.8和防火测试。我在这个方案中编写我的测试:我有测试类,我有使用testng @Test注释的方法。 它看起来像这样:

@Test(description="click Save Button ", dependsOnMethods = { "edit form" }) public void clickSaveButton(ITestContext context) { page.clickSaveButton(driver); } 

然后,正如你所看到的,我有一个页面类,我存储元素id,xpath等。它像这样lokks:

 public void clickSaveButton(WebDriver driver){ Configuration.clickfoundElement(By.id(conf.get("saveButton")), driver); } 

conf是表示属性文件的对象。 最后我有Configuration类,我在这里做了一些思考:

 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
"); if(attempts==9){ throw(e); } } catch(StaleElementReferenceException e) { System.out.println("StaleElementReferenceException"); Reporter.log("StaleElementReferenceException
"); 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,您有几个选择:

  1. 每次使用时都要使用定位器找到元素。
  2. 使用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 。

谢谢大家的时间。 事实certificate我的问题发生了,因为我在测试的应用程序中有类似popup winowow的东西(richFaces rich:modalPanel准确)。 这导致DOM“落后”这个弹出窗口仍然可见,但是由于它而无法点击其中的元素。 什么解决了我的问题只是等待一点点元素可以点击通过ExpectedConditions.elementToBeClickable(By by),这确保我的弹出窗口在关闭它之后消失并且点击另一个元素是可能的。 这使得Ardesco的答案最好。 再次感谢你。

您没有在while循环中递增尝试变量。 我不知道一个正确的方法,但我不会使用while循环来搜索元素。 也许你应该尝试使用driver.findElements()而不是driver.findElement()并使用一些断言。 例如,尝试检查按钮是否确实存在。

我可能会通过创建一个By变量来解决这个问题,然后将该变量传递给页面对象中的以下方法,如下所示:

 By saveButton = By.id("saveButton"); public By getSaveButton() { waitForElementPresent(saveButton, 15); return driver.findElement(saveButton); } public void waitForElementPresent(final By locator, int timeout) { ExpectedCondition e = new ExpectedCondition() { public Boolean apply(WebDriver driver) { return driver.findElements(locator).size() > 0; } }; WebDriverWait wait = new WebDriverWait(driver, timeout); wait.until(e); } 

预期条件可以改变为所需条件。 然后在测试中,单击保存按钮:

 page.getSaveButton().click(); 

至于IE8上没有发生的click(),我看到了与RemoteWebDriver类似的行为。 确保您的webdriver中有正确的缩放设置,因为这似乎是click()未被正确触发的一个原因。 有些人似乎已经通过点击几次解决了这个问题,这似乎是一个肮脏的解决方案。 我对IE7,8和9 click()的解决方案是使用((JavaScriptExecutor)driver).executeScript("onclickFunction();");执行实际的onclick javascript函数((JavaScriptExecutor)driver).executeScript("onclickFunction();");

这只是可接受的,因为测试主断言不是应该调用javascript函数onclick而是测试javascript函数动态地向页面添加元素。

关于StaleElementReferenceException,我会在每个测试中实例化一个新的页面对象,这样你就不会得到陈旧的元素,而是从一个干净的状态开始。 在JUnit4中,这将在你的@Before方法中。