Waiting in QUnit tests
Asked Answered
N

3

15

I have jQuery code that when I click on a link it first hides and then removes some HTML, like so:

$(this).parent().parent().hide('slow', function () {
    $(this).remove();
});

I want to make a QUnit test that makes sure that the HTML in question was deleted:

$(thelink).click();

// Check that it is gone, by finding the first item in the list
entity = input.form.find('.recurrenceinput_occurrences .occurrence span.action a')[0];
// And make sure it's NOT the deleted one:
ok(entity.attributes.date.value !== "20110413T000000");

The problem is of course that the ok() test is run before the hide animation has run to an end, so the offenting HTML hasn't been removed yet, and the test fails.

I've tried various ways of delaying/stopping the test for a second or so, but nothing seems to work. The most obvious one is to use an asynTest and do

stop();
setTimeout(start, 2000);

But this doesn't actually stop the test. It does seem to stop something for two seconds, but I'm not sure what. :-)

Any ideas?

Nitrate answered 18/11, 2011 at 14:37 Comment(0)
R
22

Your test should look something like this.

test('asynchronous test', function() {
    stop(); // Pause the test 
    //Add your wait
    setTimeout(function() {
       //Make assertion 
       ok(true);
       // After the assertion called, restart the test
       start();
    }, 1000);
});

UPD: In QUnit 2.x functions start() and stop() are gone. It is recommended to use assert.async() instead. Updated code looks like:

    test('asynchronous test', function() {
        var done = assert.async();
        //Add your wait
        setTimeout(function() {
           //Make you assertion 
           ok(true);
           // Tell QUnit to wait for the done() call inside the timeout.
           done();
        }, 1000);
    });
Riches answered 18/11, 2011 at 14:45 Comment(3)
Bingo! That was the right order of things. :-) So stop() actually only stops the test from finishing?Nitrate
This approach was deprecated (qunitjs.com/upgrade-guide-2.x/…). @ekcrisp's answer uses the new approach.Luthuli
What a surprise that something that was asked 6 years ago is deprecated. lolRiches
A
5

You could use the promise function to fire a callback once all animations for an element are finished. This implies that you need to know on what elements the animations are run on in the test (but you don't need to know how long the animation is).

Alderson answered 18/11, 2011 at 14:50 Comment(1)
It's an interesting idea, but I'm stuck on jQuery 1.4 at the moment, so no can do.Nitrate
W
4

using the QUnit assert object you can do

test("async test", function (assert) {
    var done = assert.async();
    setTimeout(function() {
            delayedPartOfTest();
            done();
        }, 20000);
    })

});
Wendalyn answered 12/4, 2016 at 21:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.