QUnit测试依赖于页面“onload”JavaScript

时间:2013-11-27 22:10:40

标签: javascript php jquery ajax qunit

我有一个包含大量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()还没有完成运行吗?我不明白为什么以上这些方法都不适合我...

0 个答案:

没有答案