如何使用Selenium测试Ajax应用程序并保持其稳定?

如何使用Selenium测试Ajax应用程序并保持其稳定?,ajax,testing,selenium,Ajax,Testing,Selenium,我们的团队一直在使用Selenium测试我们的应用程序,因为它是由JavaScript驱动的,我们总是遇到测试偶尔失败的问题。随着测试数量的增加,一次完整运行中至少有一次和两次测试失败的可能性已成为必然 我们最近发现,可能存在一个竞争条件,在初始化JavaScript有机会将事件处理程序附加到被单击的元素之前,selenium将单击链接。当然,在这一点上,我们正在寻找的影响没有发生,我们得到了一个失败的测试 目前,我们在单击之前增加了一点延迟,以使初始化JavaScript代码有时间完成,这显然

我们的团队一直在使用Selenium测试我们的应用程序,因为它是由JavaScript驱动的,我们总是遇到测试偶尔失败的问题。随着测试数量的增加,一次完整运行中至少有一次和两次测试失败的可能性已成为必然

我们最近发现,可能存在一个竞争条件,在初始化JavaScript有机会将事件处理程序附加到被单击的元素之前,selenium将单击链接。当然,在这一点上,我们正在寻找的影响没有发生,我们得到了一个失败的测试

目前,我们在单击之前增加了一点延迟,以使初始化JavaScript代码有时间完成,这显然有点不成熟,增加了总体测试执行的时间,并且不能保证测试不会仍然失败,因此我们正在寻找更好的解决方案

到目前为止,我们提出的最好的想法是在触发click事件之前,将一个隐藏元素注入到DOM中,Selenium可以等待它。当我们处理异步事件、删除和添加元素时,这将在开发人员时间方面产生大量额外的开销。此外,它还为我们的页面添加了应用程序真正不需要的额外内容


有谁有更好的策略吗?你做了什么来有效地解决这个问题?

我做的和你完全一样:添加一些延迟,等待页面上出现一些元素。我完全同意。也许切换到Webdriver/selenium 2.0会有所帮助。如果您使用内存中的数据库,或者在测试之间共享同一个selenium/selenium服务器,或者甚至使用并行化(例如TestNG很容易),那么可以减少测试执行。

我们转到了selenium 2(WebDriver)并与PageFactory/AjaxElementLocatorFactory一起使用-这方面的一个示例是

您是否尝试了waitForElementPresent命令,然后使其单击?

要消除竞争条件,请使用Selenium的
运行脚本(String initCondition)
waitForCondition(String jsConditional,String timeout)结合使用
方法

例如,如果要测试的AJAX功能导致向dom中添加新元素,则可以使用如下内容

String jsPoll = "";
jsPoll += "selenium.browserbot.getCurrentWindow()";
jsPoll += ".document.getElementById('DOMID')";
selenium.waitForCondition(jsPoll, "30000");
String jsInit = "";
jsInit += "!selenium.browserbot.getCurrentWindow()";
jsInit += ".document.getElementById('DOMID').setAttribute('SELENIUMTEST','1')";
String jsPoll = "";
selenium.runScript(jsInit);
jsPoll += "selenium.browserbot.getCurrentWindow()";
jsPoll += ".document.getElementById('DOMID').getAttribute('SELENIUMTEST') != 1";
selenium.waitForCondition(jsPoll, "30000");
当添加元素时,条件将计算为true,并且方法将继续。如果AJAX函数交换元素(即:一个div替换另一个类似标识的div),则可以使用如下内容初始化条件

String jsPoll = "";
jsPoll += "selenium.browserbot.getCurrentWindow()";
jsPoll += ".document.getElementById('DOMID')";
selenium.waitForCondition(jsPoll, "30000");
String jsInit = "";
jsInit += "!selenium.browserbot.getCurrentWindow()";
jsInit += ".document.getElementById('DOMID').setAttribute('SELENIUMTEST','1')";
String jsPoll = "";
selenium.runScript(jsInit);
jsPoll += "selenium.browserbot.getCurrentWindow()";
jsPoll += ".document.getElementById('DOMID').getAttribute('SELENIUMTEST') != 1";
selenium.waitForCondition(jsPoll, "30000");

当AJAX函数调出元素时,条件的计算结果为true。

当然,还有优秀的Selenium网格,可以跨多台机器同时运行大量测试。这就是我们最终所做的。打算以后再解决。它基本上是稳定的,但一些测试仍然偶尔出现问题。我想这只是一场持续的战斗。Thx,现在你让我想重写我们所有的Selenium测试以使用页面对象模式:)