问题描述
简要说明
将测试服务器重置为已知状态会导致我的测试失败,原因是DataTables实例在服务器复位时正在进行的Ajax请求。我想通过在服务器重置之前停止DataTables请求来阻止这种情况。
详细说明
我有一个应用程序,我在一些页面上使用DataTables。这些DataTable都执行服务器端查询来填充它们的表。
当我进行系统测试时,有时会出现竞争条件:
-
测试运行器启动测试服务器。
-
测试运行器在测试浏览器中加载了一个DataTable实例的页面。
-
测试运行器运行测试,执行检查和结束。
-
测试运行程序将测试服务器重置为已知状态进行下一次测试。
-
页面上显示一条警报,表示DataTables遇到Ajax错误。警报说:
- 我的测试系统,不期待警报,被困惑,甚至注册失败虽然测试其实是成功的。 (或者在某些情况下,它会崩溃。)
我知道这是因为服务器突然中断了Ajax请求。我正在寻找的是防止警报首先出现的一种方法。我想在重置服务器之前停止所有正在进行的DataTable请求
解决方案已被拒绝
-
告诉DataTables实例不使用警报:如果DataTables实例遇到与重置无关的问题,我希望我的测试失败测试服务器。
-
修改测试服务器:我喜欢保持服务器简单,不用担心有关可能会发生的请求没有答复。
-
等待客户端所有请求结束:这可能会大大减慢测试速度,特别是当这种等待重复数十次测试时。 / p>
-
将测试浏览器引导到一个新的页面,没有DataTable,因为这样会中断当前的请求:再次会影响测试性能。
解决方案
驱动浏览器的软件执行以下公司de在浏览器中经过测试完成所有检查。 (这将是测试后运行的某种拆除代码。)
if(typeof $!== undefined& $ .fn.dataTable){
var all_settings = $($。fn.dataTable.tables())。DataTable()。settings();
for(var i = 0,settings;(settings = all_settings [i]); ++ i){
if(settings.jqXHR)
settings.jqXHR.abort();
}
}
说明
即使在没有加载jQuery或没有加载DataTable的页面上执行,代码也被写入工作。所以它首先检查它们是否加载,如果没有加载,它们不会执行任何操作。然后它将获取所有DataTable实例的设置对象。在每个设置对象中,它检查是否存在 jqXHR
,它填充了一个jQuery 对象。它将调用 abort()
方法,从而中止请求。
上面的代码与DataTables配合使用1.10表是否使用1.10 API或1.9 API。但是请注意, jqXHR
字段不是公共API的正式组成部分。与此同时,其中一个开发者谈论它,而不必在,所以这可能不是私有API依赖的最危险的部分。而纯粹依赖于公共API的解决方案将会更加繁琐,因为所有DataTable实例都必须进行修改,以跟踪标记Ajax事务开始的事件及其结束或已定制的Ajax处理程序等。要做的不仅仅是正在测试的项目的代码,而且是提供使用DataTables的HTML小部件的任何第三方库。
请注意,上面的代码不阻止数据表实例启动新的请求。但这不是我所关心的。
Brief Description
Resetting a test server to a known state causes my tests to fail due to Ajax requests launched by DataTables instances being ongoing at the time the server is reset. I'd like to prevent this by stopping the DataTables requests before the server is reset.
Detailed Description
I have an application in which I use DataTables on some pages. These DataTables all perform server-side queries to populate their tables.
When I perform system testing, sometimes there is a race condition that can happen:
The test runner starts the test server.
The test runner loads in a test browser a page with a DataTable instance somewhere on it.
The test runner runs the test, which performs its checks and ends.
The test runner resets the test server to a known state for the next test.
An alert shows up on the page, saying that DataTables experienced an Ajax error. The alert says:
- My testing system, which is not expecting the alert, is confused and registers a failure even though the test was in fact successful. (Or in some cases, it crashes.)
I know this happens because the server abruptly interrupted an Ajax request. What I am looking for is a way to prevent the alert from coming up in the first place. I'd like to stop all ongoing DataTables requests before the server is reset.
Solutions already rejected
Tell the DataTables instances not to use alerts: I want my tests to fail louldly if a DataTables instance runs into an issue that is not related to resetting the test server.
Modifying the test server: I prefer to keep the server simple and not worry there about requests that may go unanswered.
Wait client-side for all requests to be over: this can slow down tests considerably, especially when this wait is repeated for dozens of tests.
Direct the test browser to a new page, without DataTables on it, as this will interrupt the current requests: again this will hurt test performance.
Solution
Have the software that drives the browser execute the following code in the browser after a test has completed all its checks. (This would be in some sort of "tear down" code run after the test.)
if (typeof $ !== "undefined" && $.fn.dataTable) {
var all_settings = $($.fn.dataTable.tables()).DataTable().settings();
for (var i = 0, settings; (settings = all_settings[i]); ++i) {
if (settings.jqXHR)
settings.jqXHR.abort();
}
}
Explanation
The code is written to work even when executed on pages that don't have jQuery loaded or don't have DataTables loaded. So it first checks whether they are loaded, and does not do anything if they are not loaded. Then it fetches the settings objects for all DataTable instances. In each settings objects, it checks for the presence of jqXHR
, which is populated with a jQuery jqXHR
object when an Ajax request has been made. It will call the abort()
method on it, thus aborting the request.
The code above works with DataTables 1.10 whether the tables use the 1.10 API or the 1.9 API. However, note that the jqXHR
field is not formally part of the public API. At the same time, one of the devs speaks about it without caveat on DataTables forum, so this is probably not the riskiest part of the private API to rely on. And a solution that relies purely on the public API would be much more cumbersome as all DataTable instances would have to be modified to track the events that mark the start of an Ajax transaction and its end or have customized Ajax handlers, etc. This would have to be done not only for the code proper to the project being tested but any 3rd party library that provides HTML widgets that happen to use DataTables.
Note that the code above does not prevent DataTables instances from initiating new requests. But this is not a concern I have.
这篇关于如何停止DataTables实例已经开始的所有正在进行的Ajax查询?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!