我有一个包含大量select元素的表单,所有这些元素都是使用AJAX从页面加载的数据库中填充的。
来自test_form.js.html的代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Testing: 'form.js'</title>
<link type="text/css" rel="stylesheet" href="css/qunit-1.12.0.css" />
<script type="text/javascript" src="js/qunit-1.12.0.js"></script>
<script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="js/form.js"></script>
</head>
<body onload="initialLoad();">
<div id="qunit"></div>
<div id="qunit-fixture">
<form action="" method="POST" id="caseEntryForm">
...form stuff...
<label for="CourtOfOrigin">Court of Origin</label>
<select name="CourtOfOrigin" id="CourtOfOrigin">
<option value="">--error--</option>
</select>
...form stuff...
</form>
<div>
<script>
// QUnit auto start has been set to false so onload can finish first, so start the test engine
QUnit.start();
// Testing CrossAppeal onchange listening function
test( "CrossAppeal onchange listening function Test", function() {
...assertions that all pass if this is the first test to run...
});
// Testing Outcome onchange listening function
test( "Outcome onchange listening function Test", function() {
...assertions that all pass if this is the first test to run...
});
</script>
</body>
</html>
来自form.js的代码:
function initialLoad(){
$.post('processAjax.php', { field: 'Courts' }, function (data) {
var target = $("#Outcome");
target.empty();
target.append('<option value="">--select--</option>');
for (var i=0; i<options.length; i++) {
target.append('<option value="' + data[i].Value + '">' + data[i].Option + '</option>');
}
}
...about ten more ajax calls populating select elements from different tables...
}
来自processAjax.php的代码:
require('config.php');
if (isset($_POST['field'])) {
if ($_POST['field'] == 'Courts') {
// Process Ajax requests to load the CourtOfOrigin and SCOrigin <select>s
$results = $mysqli->query("SELECT CourtName FROM ref_courts");
$returnArray = array();
while ($row = $results->fetch_assoc()) {
$returnArray[] = array('Value' => $row['CourtName'], 'Option' => $row['CourtName']);
}
echo json_encode($returnArray);
} else if ( ... ) {
...further ifs that handle other select elements and tables...
}
...
}
因此,就形式而言,所有这些都可以正常工作。调用始终正常工作并正确填充选择对象。
现在我正在尝试使用QUnit来测试form.js中基于用户输入操作表单中对象的所有其他函数。 (即根据select元素中选择的选项显示/隐藏元素。)如果我只运行一个测试,这个工作正常,我的所有测试都通过了。但是,只要我添加第二个测试,测试就会在传递和失败之间开始交替。
我已经对此进行了彻底的研究,但我确切知道为什么会这样,但是我不能为我的生活找到解决方案。
原因是,第一次测试完成后,QUnit会根据需要重置“qunit-fixture”div。但它重新将其重置回初始代码,在那里,在调用onload JavaScript函数之前,这意味着我的select元素现在再次为空,从而导致下一个测试失败。然后刷新导致它们切换哪一个通过并失败的原因是因为QUnit首先运行失败的测试。我理解这一切,这是有道理的。
我需要做的是以某种方式在每个测试之间运行initialLoad()函数,因为这是表单的真实初始状态。如果我将选择选项硬编码到测试表单中,我显然可以解决这个问题,但我宁愿不这样做,因为我觉得这不会真正测试JavaScript,加上一些选择有很多选项。
我花了几个小时试图找到解决方案,但到目前为止还没有发现任何有效的方法。我尝试在每次测试开始时调用initialLoad(),但这不起作用,因为测试将在AJAX调用实际返回之前完成。我也尝试过使用stop()和start(),但没有成功。 (这可能仅仅是一个实施问题?)
这就是我尝试做stop()的方法:
// Testing Outcome onchange listening function
test( "Outcome onchange listening function Test", function() {
stop();
initialLoad();
setTimeout(function() {
ok(true);
start();
}, 500 );
...assertions that all pass if this is the first test to run...
}
但是,他们仍然无法交替刷新。
所以我尝试这样做:
// Testing Outcome onchange listening function
test( "Outcome onchange listening function Test", function() {
stop();
initialLoad();
setTimeout(function() {
...assertions that all pass if this is the first test to run...
start();
}, 500 );
}
我的结果好坏参半。以前,所有断言都失败了。但现在,所有处理每次更改所选值PASS的断言,所以选择对象现在显然已填充。但是,当这些选项被更改时,它应该触发一个显示/隐藏元素的函数。这些断言在每个交替时间都失败。 (无论我在函数的开头还是结尾都有start(),我都会遇到相同的情况。)我已经尝试将超时提高到10,000,但没有区别。
所以我觉得我正在走上正轨,但我不确定为什么onchange功能没有在交替刷新时执行......似乎没有任何理由为什么会发生这种情况,当时似乎每次都满足条件......
更新:在尝试帮助其他人解决问题时,我遇到了QUnit.testStart()和QUnit.testDone(),这听起来像是可以用来解决问题。我认为调用“initialLoad();”在每次测试之前,在testStart()中确保夹具在每次测试运行之前都处于正确的状态,但是我仍然得到相同的交替结果。这是因为initialLoad()还没有完成运行吗?我不明白为什么以上这些方法都不适合我...