对于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[@class='error-summary']"))
// maybe some more verification here to check the expected errors// ... correct error and resubmitsubmitButton.click()
waitForElementRemoval(By.xpath("//div[@class='error-summary']"))
waitForElementRemoval(By.id("windowId"))

从示例中可以看到,您的代码可以专注于实际的测试逻辑,同时无缝地处理GWT应用程序的异步特性。

问题2:在您对DOM几乎没有控制的情况下定位元素

在使用模板的Web应用程序(JSP,Velocity,JSF等)中,您可以很好地控制并轻松查看页面将具有的DOM结构。 对于GWT,情况并非总是如此。 通常,您正在处理无法精确控制的嵌套元素。

使用WebDriver和Selenium,可以使用几种方法来定位元素,但最有用的是DOM元素ID和XPath。 我们如何利用它们来获得可维护的测试,而这些测试不会因布局的微小变化而中断?

解决方案:结合使用XPath和ID来限制范围

以我的经验,要在WebDriver中开发功能性GWT测试,您应该使用稍微松散的XPath作为查找元素的主要方法,并在适用时通过DOM ID对这些调用进行作用域来对其进行补充。

特别是,请在应用程序中唯一的窗口或选项卡等顶级元素上使用ID,这些ID在页面中不会出现多次。 这些可以帮助确定您的XPath表达式的范围,该表达式可以查找窗口或表单标题,字段标签等。

以下是一些示例,可助您一臂之力。 请注意,我们在XPath中使用//和*来保持表达式的灵活性,以便除非主要更改布局更改,否则不会破坏我们的测试。

By byUserName = By.xpath("//*[@id='userTab']//*[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("//*[@id='userTab']//input[@type='submit']")
WebElement submit = webDriver.findElement(submitLocator)
submit.click()// use our helper method from Problem 1
waitForElementRemoval By.id("userTab")

问题3:法线元素交互方法不起作用!

就管理DOM的状态而言,GWT及其派生工具(Vaadin,GXT等)通常在幕后发挥作用。 对开发人员来说,这意味着您不必总是处理普通的<input>或<select>等元素。 仅通过常规方法简单地设置字段的值可能不起作用,并且使用WebDriver或Selenium的click方法可能不起作用。

WebDriver在这方面有所改进,但是问题仍然存在。

解决方案:不幸的是,只有一些解决方法

您可能会遇到的主要问题与在字段中键入和单击元素有关。

以下是一些我过去发现有必要的变体,可以避免点击无法正常运行。 如果遇到问题,请尝试一下。 这些示例在Selenium中,但是如果需要,可以将它们改编为适用于WebDriver中的相应调用。 如果您想直接使用示例,也可以将Selenium适配器用于WebDriver(WebDriverBackedSelenium)。

点击问题
有时,元素不会响应Selenium或WebDriver中的click()调用。 在这些情况下,通常必须在浏览器中模拟事件。 Selenium在2.0之前比WebDriver更是如此。

// Selenium's 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() aren't 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, i+1)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

使用Selenium或WebDriver测试GWT应用相关推荐

  1. Python3 Selenium自动化web测试 == 第三节 常用WebDriver API使用示例上(24个API)

    前置步骤: 安装selenium,chrome驱动,Python3.6 学习目的: 常见API的使用 涉及的API: step1: 访问一个网址 step2: 网页的前进和后退 step3: 刷新当前 ...

  2. 使用Selenium WebDriver测试自动化的22条实用技巧

    使用Selenium进行测试自动化已使全球的网站测试人员能够轻松执行自动化的网站测试. Webdriver是Selenium框架的核心组件,通过它您可以针对不同类型的浏览器(例如Google Chro ...

  3. linux firefox xvfb,自动化测试之linux+xvfb+selenium+firefox+python测试环境搭建与测试

    1. Xvfb 为一个X虚拟框架,这个框架使用虚拟内存能让linux系统图形界面服务器(X-Server)运行在没有显示设备的机器上,这样,浏览器就可以运行了. (1) 安装xvfb 需根据自己lin ...

  4. python selenium自动化断言_python+selenium自动化登录测试,设计不同场景进行登录,两种方式断言,截图保存...

    # coding : utf-8 # date :2019/1/7 # 根据不同场景做自动化登录测试 # 正确账号密码.正确账户错误密码.等其他场景 from selenium import webd ...

  5. python数据驱动读取用例_Python Selenium 之数据驱动测试

    数据驱动模式的测试好处相比普通模式的测试就显而易见了吧!使用数据驱动的模式,可以根据业务分解测试数据,只需定义变量,使用外部或者自定义的数据使其参数化,从而避免了使用之前测试脚本中固定的数据.可以将测 ...

  6. 开源you-get项目爬虫,以及基于python+selenium的自动测试利器

    写在前面 爬虫和自动测试,对于python来说是最合适不过也是最擅长的. 开源的项目也很多,例如you-get项目https://github.com/soimort/you-get.盗链和爬虫神器. ...

  7. selenium 示例_Selenium测试中所需的功能和示例

    selenium 示例 所需功能是用于声明一组基本要求(例如浏览器,操作系统,浏览器版本等的组合)的类,以对Web应用程序执行自动跨浏览器测试. 当我们尝试通过Selenium自动化测试来自动化测试脚 ...

  8. 盖得化工--selenium翻页测试

    Python爬虫视频教程零基础小白到scrapy爬虫高手-轻松入门 https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.482434a6E ...

  9. Selenium学习 - WebDriver接口

    Selenium学习 - WebDriver接口 一.WebDriver的初始化 def __init__(self,                    command_executor='htt ...

最新文章

  1. 1.6万亿参数,秒杀GPT-3!谷歌推出超级语言模型Switch Transformer,比T5快4倍
  2. linux控制台界面编程,控制台窗口界面的编程控制(二)
  3. xp,win7,win2003,win2008常用命令集
  4. linux find 排除某目录或文件 执行
  5. ArcGIS实验教程——实验十一:影像拼接与提取
  6. 新入职了一个卷王 , 天天加班12点!张口闭口就手写spring , 太让人崩溃了......
  7. MFC控件——ListCtrl控件[翻译](续)
  8. html非封闭标签,自封闭的html标签
  9. 光猫gpon和epon的区别
  10. Hadoop学习之SecondaryNameNode
  11. 免费数据集下载(很全面)
  12. Si4463/Si4432/Si4438无线射频RF方案
  13. linux检查系统内存,Linux查看内存使用情况方法
  14. 基于FBX SDK的FBX模型解析与加载
  15. counter计数器
  16. 滚球板球控制系统详解(openmv+stm32实现)
  17. [ 网络协议篇 ] IGP 详解之 RIP 详解(一)
  18. 《父与子的编程之旅——Python》(一)序章-第一章-第二章
  19. SWUST OJ 954单链表的链接
  20. html input禁止驶入,layui form表单 input输入框获取焦点后 阻止Enter回车自动提交 – 执念 – 博客园...

热门文章

  1. nacos启动失败:org.springframework.boot.web.server.WebServerExceptio
  2. mongodb json_在MongoDB和Spring Batch中将XML转换为JSON和原始使用
  3. openshift_Openshift源中的高可用性Drools无状态服务
  4. 如何使用java代码生成_使用Java成功生成代码的7个技巧
  5. java面包屑实现_在Java中实现过滤器和面包店锁
  6. swagger api文档_带有Swagger的Spring Rest API –公开文档
  7. spring bean依赖_Spring @Configuration并将bean依赖项作为方法参数注入
  8. apache camel_在WildFly中将Apache Camel和Spring添加为jboss模块
  9. java备忘录_Java 8备忘单中的可选
  10. spring aop示例_Spring JpaRepository示例(内存中)