I've got some mocha tests that require data from prior function calls. However, because my code is using a web service, I would like it to wait for a predetermined amount of time before running the next test.
Something like this:
var global;
it('should give some info', function(done) {
run.someMethod(param, function(err, result) {
global = result.global
done();
});
});
wait(30000); // basically block it from running the next assertion
it('should give more info', function(done) {
run.anotherMethod(global, function(err, result) {
expect(result).to.be.an('object');
done();
});
});
Any ideas would be appreciated. Thanks!
According to it, tests are run synchronously. This only shows that ordered code is run in order. That doesn't happen by accident.
Retrying Mocha tests Mocha provides a this. retries() function that allows you specify the number of times a failed test can be retried. For each retry, Mocha reruns the beforeEach() and afterEach() Hooks but not the before() and after() Hooks.
This inclusive ability is available in Mocha by appending . skip() to the suite or to specific test cases. The skipped tests will be marked as "pending" in the test results.
Mocha does not run individual tests in parallel. If you only have one test file, you'll be penalized for using parallel mode.
setTimeout
definitely could help, but there may be a "cleaner" way to do it.
The documentation here actually says to use this.timeout(delay)
to avoid timeout errors while testing async code, so be careful.
var global;
it('should give some info', function(done) {
run.someMethod(param, function(err, result) {
global = result.global
done();
});
});
it('should give more info', function(done) {
this.timeout(30000);
setTimeout(function () {
run.anotherMethod(global, function(err, result) {
expect(result).to.be.an('object');
done();
});
}, 30000);
});
While this.timeout()
will extend the timeout of a single test, it's not the answer to your question. this.timeout()
sets the timeout of your current test.
But don't worry, you should be fine anyway. Tests are not running in parallel, they're done in series, so you should not have a problem with your global approach.
In my case, I was coding a RESTful API
in NodeJS
that was manipulating some files locally. As I was launching the tests, the API was receiving multiple requests and it makes my API manipulate, concurrently, these files in the machine, which led me to a problem.
So, I needed to put some time (1 sec
was enough) between these API calls. For me, the solution was the following one:
beforeEach( async () => {
await new Promise(resolve => setTimeout(resolve, 1000));
console.log("----------------------");
});
Now, before each it()
test, the previous function is run, and I have a sleep of 1 second between API calls.
First:
This thread has great answers! I personally Liked @Flops answer (got my upvote)
Second:
To clarify this (as much as possible) here is a code sample very similar to the one I ended up with (tested and verified)
function delay(interval)
{
return it('should delay', done =>
{
setTimeout(() => done(), interval)
}).timeout(interval + 100) // The extra 100ms should guarantee the test will not fail due to exceeded timeout
}
it('should give some info', function(done) {
run.someMethod(param, function(err, result) {
global = result.global
done();
});
});
delay(1000)
it('should give more info', function(done) {
run.anotherMethod(global, function(err, result) {
expect(result).to.be.an('object');
done();
});
});
Side note: you can also use delay functions one after another and still preserve consistency (tests order)
First of all, for proper unit testing, you should never need some sleep between tests. If you do need a sleep, this means the functions you are testing require a delay before completing its expected task, which must be handled inside that function, with some asynchronous wait or sleep. Upon exit from a function, its lifetime must end and the expected result must be acquired immediately.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With