旅游类作业网站,广告营销策划是做什么的,网站建设ASP心得体会,wordpress 页面压缩对于Web应用程序开发人员及其团队而言#xff0c;良好的功能测试是最困难的任务之一。 开发价格低廉且维护良好的测试是一项挑战#xff0c;这有助于降低质量检查成本并提高质量。 Selenium和WebDriver#xff08;本质上现在是Selenium的继承者#xff09;都提供了一种无需… 对于Web应用程序开发人员及其团队而言良好的功能测试是最困难的任务之一。 开发价格低廉且维护良好的测试是一项挑战这有助于降低质量检查成本并提高质量。 Selenium和WebDriver本质上现在是Selenium的继承者都提供了一种无需人工就可以在多个目标环境中对Web应用程序进行功能测试的好方法。 过去Web UI是使用页面导航构建的以允许用户提交表单等。如今越来越多的Web应用程序使用Ajax因此其行为和外观与桌面应用程序非常相似。 但是这给测试带来了问题– Selenium和WebDriver旨在与用户交互配合使用从而导致页面导航并且不能与现成的AJAX应用很好地配合使用。 基于GWT的应用程序尤其存在此问题但是我发现有一些方法可以开发有用且有效的测试。 在模拟用户输入和查找DOM元素方面GWT还提出了其他问题我将在下面进行讨论。 请注意我的代码示例使用Groovy使其简洁但是可以很容易地将它们转换为Java代码。 问题1处理异步更改 在测试基于GWT的应用程序时开发人员很快就会面临的一个问题是检测并等待对用户交互的响应。 例如用户可以单击导致AJAX调用的按钮该调用将成功并关闭窗口或者显示错误消息。 我们需要的是一种阻止方法直到我们看到预期的变化并且超时这样如果我们看不到预期的变化我们可能会失败。 解决方案使用WebDriverWait 最简单的方法是利用WebDriverWait或Selenium的Wait。 这使您可以等待条件并在条件评估为true时继续进行。 下面为了简洁地使用闭包我使用了Groovy代码但是在Java中也可以做到这一点尽管由于需要匿名类所以使用了更多代码。 def waitForCondition(Closure closure) {int timeout 20WebDriverWait w new WebDriverWait(driver, timeout)w.until({closure() // wait until this closure evaluates to true} as ExpectedCondition)
}def waitForElement(By finder) {waitForCondition {driver.findElements(finder).size() 0;}
}def waitForElementRemoval(By finder) {waitForCondition {driver.findElements(finder).size() 0;}
}// now some sample test code submitButton.click() // submit a form// wait for the expected error summary to show up
waitForElement(By.xpath(//div[classerror-summary]))
// maybe some more verification here to check the expected errors// ... correct error and resubmitsubmitButton.click()
waitForElementRemoval(By.xpath(//div[classerror-summary]))
waitForElementRemoval(By.id(windowId)) 从示例中可以看到您的代码可以专注于实际的测试逻辑同时无缝地处理GWT应用程序的异步特性。 问题2在您对DOM几乎没有控制的情况下定位元素 在使用模板的Web应用程序JSPVelocityJSF等中您可以很好地控制并轻松查看页面将具有的DOM结构。 对于GWT情况并非总是如此。 通常您正在处理无法精确控制的嵌套元素。 使用WebDriver和Selenium可以使用几种方法来定位元素但最有用的是DOM元素ID和XPath。 我们如何利用它们来获得可维护的测试而这些测试不会因布局的微小变化而中断 解决方案结合使用XPath和ID来限制范围 以我的经验要在WebDriver中开发功能性GWT测试您应该使用稍微松散的XPath作为查找元素的主要方法并在适用时通过DOM ID对这些调用进行作用域来对其进行补充。 特别是请在应用程序中唯一的窗口或选项卡等顶级元素上使用ID这些ID在页面中不会出现多次。 这些可以帮助确定您的XPath表达式的范围该表达式可以查找窗口或表单标题字段标签等。 以下是一些示例可助您一臂之力。 请注意我们在XPath中使用//和*来保持表达式的灵活性以便除非主要更改布局更改否则不会破坏我们的测试。 By byUserName By.xpath(//*[iduserTab]//*[text()User Name]/..//input)
WebElement userNameField webDriver.findElement(byUserName)
userNameField.sendKeys(my new user)// maybe a user click and then wait for the window to disappear
By submitLocator By.xpath(//*[iduserTab]//input[typesubmit])
WebElement submit webDriver.findElement(submitLocator)
submit.click()// use our helper method from Problem 1
waitForElementRemoval By.id(userTab) 问题3法线元素交互方法不起作用 就管理DOM的状态而言GWT及其派生工具VaadinGXT等通常在幕后发挥作用。 对开发人员来说这意味着您不必总是处理普通的input或select等元素。 仅通过常规方法简单地设置字段的值可能不起作用并且使用WebDriver或Selenium的click方法可能不起作用。 WebDriver在这方面有所改进但是问题仍然存在。 解决方案不幸的是只有一些解决方法 您可能会遇到的主要问题与在字段中键入和单击元素有关。 以下是一些我过去发现有必要的变体可以避免点击无法正常运行。 如果遇到问题请尝试一下。 这些示例在Selenium中但是如果需要可以将它们改编为适用于WebDriver中的相应调用。 如果您想直接使用示例也可以将Selenium适配器用于WebDriverWebDriverBackedSelenium。 点击问题 有时元素不会响应Selenium或WebDriver中的click调用。 在这些情况下通常必须在浏览器中模拟事件。 Selenium在2.0之前比WebDriver更是如此。 // Seleniums click sometimes has to be simulated with events.
def fullMouseClick(String locator) {selenium.mouseOver locatorselenium.mouseDown locatorselenium.mouseUp locator
}// In some cases you need only mouseDown, as mouseUp may be
// handled the same as mouseDown.
// For example, this could result in a table row being selected, then deselected.
def mouseOverAndDown(String locator) {selenium.mouseOver locatorselenium.mouseDown locator
} 打字问题 这些是过去在GWT无法识别键入的输入时能够成功使用的回旋输入法。 // fires only key events (works for most GWT inputs)
// Useful if WebDriver sendKeys() or Selenium type() arent cooperating.
def typeWithEvents(String locator, String text) {def keyEvents [keydown, keypress, keyup]typeWithEvents(locator, text, keyEvents)
}// fires key events, plus blur and focus for really picky cases
def typeWithFullEvents(String locator, String text) {def fullEvents [keydown, keypress, keyup, blur, focus]typeWithEvents(locator, text, fullEvents)
}// use this directly to customize which events are fired
def typeWithEvents(String locator, String text, def events) {text.eachWithIndex { ch, i -selenium.type locator, text.substring(0, i1)events.each{ event -selenium.fireEvent locator, event}}
} 请注意必须通过反复试验找出有效的方法在某些情况下您在不同的浏览器中可能会得到不同的行为因此如果针对不同的环境运行功能测试则必须确保您的方法适用于所有这些方法。 结论 希望你们中的一些人发现这些技巧有用。 那里也有类似的技巧但我想汇编一套很好的示例和变通方法以使处于类似情况的其他人不会陷入僵局也不会在需要大量猜测和时间的问题上浪费时间。 参考 Carfey Software博客上的JCG合作伙伴提供的使用Selenium或WebDriver测试GWT应用程序 。 相关文章 任何软件开发公司应存在的服务实践和工具第2部分 为什么自动化测试可以提高您的开发速度 不执行代码审查 你的借口是什么 软件可靠性的教训 这是在您的业务逻辑之前 单元和集成测试的代码覆盖率 翻译自: https://www.javacodegeeks.com/2011/10/testing-gwt-apps-with-selenium-or.html