Javascript Qunit测试在页面刷新时交替进行通过和失败

Javascript Qunit测试在页面刷新时交替进行通过和失败,javascript,jquery,unit-testing,qunit,Javascript,Jquery,Unit Testing,Qunit,我有两个测试,它们相互之间会产生副作用。我理解为什么要替换在第二次测试中内部调用的jQuery内置函数。然而,我不明白的是为什么测试交替通过和失败 但是,我没有直接在qunit fixture div上执行任何操作 这是我的测试 test('always passing test', function() { // Always passes var panelId = '#PanelMyTab'; var event = {}; var ui = {

我有两个测试,它们相互之间会产生副作用。我理解为什么要替换在第二次测试中内部调用的jQuery内置函数。然而,我不明白的是为什么测试交替通过和失败

但是,我没有直接在qunit fixture div上执行任何操作

这是我的测试

test('always passing test', function() { // Always passes
    var panelId = '#PanelMyTab';

    var event = {};
    var ui = {
        tab: {
            name: 'MyTab',
        },
        panel: panelId,
    };

    $('<div id="' + panelId + '">')
        .append('<a href="#" class="export">Test</a>')
        .append('<a href="#" class="showForm">Show Form</a>')
        .appendTo('#qunit-fixture');

    jQuery.fn.on = function(event, callback) {
        ok(this.selector == panelId + ' .export', 'Setting export click event');
        equal(callback, tickets.search.getReport, 'Callback being set');
    };

    loadTab(event, ui);
});

test('alternately passing and failing', function() { // Alternates between passing and failing on page refresh
    expect(5);

    var testUrl = 'test';
    $('<div class="ui-tabs-panel">')
        .append('<a href="'+ testUrl + '" id="getReport">Get Report</a>')
        .append('<form action="notest" target="" class="ticketSearch"></form>')
        .appendTo('#qunit-fixture');

    // Setup form mocking
    $('form.ticketSearch').submit(function() {
        var urlPattern = new RegExp(testUrl + '$');
        ok(urlPattern.test($(this).prop('action')), 'Form action set to link href');
        equal($(this).prop('target'), '_blank', 'Open form on a new page');
    });

    var event = {
        target: 'a#getReport',
    };

    var result = getReport(event);

    var form = $('form.ticketSearch');

    ok(/notest$/.test($(form).prop('action')), 'Making sure action is not replaced');
    equal($(form).prop('target'), '', 'Making sure that target is not replaced');

    ok(false === result, 'click event returns false to not refresh page');
});

如果没有更多的信息,我不确定我能否解决这个问题,但我可以指出一些可能的问题

第一个测试第2行的语法似乎无效

var panelId = '#PanelMyTab');
但这可能是一个类型错误,正如你所说,第一个总是过去的

我假设要使第一个测试通过(并且有效),loadTab(event,ui)必须运行jQuery.fn.on(),没有它就不会运行断言。使用jQueryUI选项卡进行一些测试似乎就是这样(只是不确定这是否是您的意图)

我不确定将这些断言放在该函数中是否可取,并且您必须理解,您已经用一个不做任何事情的函数覆盖了jquery函数,因此很可能会导致问题

在第二个测试中,您似乎在做类似的事情,您期望5个断言,但我只能看到如何运行最后3个断言

ok(/notest$/.test($(form).prop('action')), 'Making sure action is not replaced');
equal($(form).prop('target'), '', 'Making sure that target is not replaced');
ok(false === result, 'click event returns false to not refresh page');
另外2个在submit函数中,该函数看起来不像是作为测试的一部分调用的

test('asynchronous test', function() {
    // Pause the test first
    stop();

    setTimeout(function() {
        ok(true);

        // After the assertion has been called,
        // continue the test
        start();
    }, 100)
})
请记住,这些测试是同步的,因此在运行测试并失败之前,不会等待您点击提交

这里有一个例子

test('asynchronous test', function() {
    setTimeout(function() {
        ok(true);
    }, 100)
})
将失败,因为测试后100毫秒运行ok

test('asynchronous test', function() {
    // Pause the test first
    stop();

    setTimeout(function() {
        ok(true);

        // After the assertion has been called,
        // continue the test
        start();
    }, 100)
})
stop()命令qunit等待,start()命令开始

api中还详细介绍了asyncTest()

最后,您似乎正在尝试使用这些测试调试代码。使用chrome开发者工具或firefox中的firebug在代码上设置断点,并使用console.log()和console.dir()输出信息会容易得多

话虽如此,我完全不知道它对您是如何工作的,因此我可能会遗漏一些东西:)如果您仍然被卡住,请查看是否可以添加更多的周围代码以及您试图实现的目标。希望这有帮助

PS:还有一个
}结尾,这在您给我们的代码中是无效的,但可能与实际应用程序相关;)

我修改了@Ben's,将您的代码包含在两个测试中。我修改了一些代码以使其正确运行。当您点击运行按钮时,所有测试都将通过。当您再次点击run按钮时,第二个测试(“交替通过和失败”)将失败——这基本上是模拟您的原始问题

问题是您的第一个测试(“始终通过测试”)通过将
jQuery.fn.on
函数替换为重写函数来更改全局状态。因此,当按顺序运行测试时,第二个测试(“交替通过和失败”)使用了不正确的重写
jQuery.fn.on
函数并失败。每个单元测试都应该将全局状态返回到其测试前状态,以便其他测试可以基于相同的假设运行

之所以在通过和失败之间交替,是因为在幕后,QUnit总是首先运行失败的测试(它通过cookie或本地存储记住了这一点,我不太确定)。当它首先运行失败的测试时,第二个测试在第一个测试之前运行;因此,第二个测试在
函数上获得jQuery的本机
,并运行。第三次运行时,测试将以“原始”顺序运行,第二次测试将使用覆盖的
on
功能并失败

这是工作表。在测试之后,我通过缓存原始
var jQueryOn=jQuery.fn.on,为
on
函数添加了“unoverride”修复程序功能,并在测试结束时通过以下方式重置它:
jQuery.fn.on=jQueryOn。您可以使用QUnit的module
teardown()
方法更好地实现这一点


您可以查看更多信息。

我认为需要先弄清楚。请输入密码。另外,
getReport
函数也是线索。请显示
getReport
函数。添加了正在测试的代码。任何语法错误都是打字错误。我试图只显示代码的相关部分。不,我不想调试这些测试。这些测试用于测试特定的事件,在这一点上,同步似乎不是问题。一半时间内,测试都按我的预期执行,但当我刷新浏览器时,结果会发生变化。这就是我的问题所在。你能解释一下,在第二次测试中,当只有3个断言看起来是同步运行的时候,你是如何得到5个断言的吗?这可能是问题的原因。我为第二次测试制作了一个小提琴模型,并删除了getReport函数。必须是getReport()调用通过调用jQuery.fn.on()生成断言,我们是否有可能看到该函数的功能?整个函数调用是同步完成的。我更新了代码以显示正在调用的函数。该函数生成表单的深度副本,更改一些参数并触发提交事件。这被我的嘲笑抓住了。问题是测试将通过,当我刷新页面时,测试将失败。然后用另一个页面刷新一遍。每次按F5交替显示结果。我认为这里没有进行任何异步测试。更简单的是,当他重新运行测试时,它在一次运行中通过,然后在下一次运行中失败。然后每次运行都会在通过和失败之间交替进行。是的,现在刚刚看到更新,抱歉。我理解刷新问题,但这可能是一个与时间有关的问题。我已经更新了小提琴,你可以在它自己的页面上查看。在IE、Chrome和firefox中,它可以顺利运行。我不得不写我自己的jQuery.fn.on(),因为我不知道发生了什么