jonadev95
jonadev95

Reputation: 367

Tests for asynchron functions which depend on the previous one with mochajs

I'm writing a set of tests for a server. Basically there are pre defined requests and the expected answers for every of them.

The tests are stored in a json file, so I could later extend it as demanded.

A few tests rely on two ID's of foregoing test, so the tests shouldn't be executed in parallel. To archive that I'm using the waterfall function of the async library, so im able to pass arguments to the next function.

The problem is, when I'm iterating through this array of tests, I'm calling it(testname, function(done){...}).In this function I execute the request and compare the response to the expected answer. After that I call the done function so mochajs knows the test is finished.

When I'm starting the tests, the first one get's executed, but no further ones.

For me it looks like that mochajs recognizes that there's currently no other test-task running, so it stops the script.

This is the test:

var testFunctions=[];

predefinedTests.forEach(function(test){
     var fn = function(error, id_1, id_2, callback){

         it("Test", function(done){
             makeAsyncRequest(test.url, function(res){
                 expect(res).to.have.properties(test.answer);
                 id_1=res.id1;
                 id_2=res.id2;
                 done();
                 /*check if it's the first test, 
                 if that's the case it needs to use the first argument as callback */
                 if(callback==undefined) return error(null, id_1, id_2);
                 callback(null, id_1, id_2);
             });
         });

     }
    testFunctions.push(fn);
});
async.waterfall(testFunctions);

Upvotes: 0

Views: 55

Answers (1)

Louis
Louis

Reputation: 151531

so the tests shouldn't be executed in parallel.

Declaring a test to be asynchronous only tells Mocha that is must wait for the test to be complete, not that it is free to run tests in parallel. Mocha does not run tests in parallel, no matter whether they are synchronous or not. So you do not have to use async to prevent Mocha from doing something it does not do in the first place. (There exist packages that you must add to your test setup if you want tests running in parallel. Like this one. Presumably, they patch Mocha to add the parallel capability.)

You should just remove the async stuff, and have your foreEach callback call it directly.

Other than this, you have set up your test suite so that one test depends on the status of a previous test. Generally, you should write your Mocha tests so that they are independent from one another. Mocha is really designed so that the tests are supposed to be run independently. For instance, if you use --grep to select only a subset of tests. Mocha won't know about the dependencies between your tests and you'll get failures if the selected tests depend on tests that were not selected. Generally, you want to put anything a test depends on in a before or beforeEach hook.

If you are in a situation where doing this would be onerous, you could keep state in a higher scope. I would not want to make it global, so I'd put everything inside a describe:

describe("all tests", function () {
    // WARNING: The following tests must be run in sequence. 
    // We have to do this because [explain here what reason requires
    // this setup].
    var id1;
    var id2;

    predefinedTests.forEach(function(test){
        it("Test", function(done){
            makeAsyncRequest(test.url, function(res){
                expect(res).to.have.properties(test.answer);
                id1=res.id1;
                id2=res.id2;
             done();
        });
    });
});

(I don't see in your question how the idX variables are used to make a new request so my code above does not show it. I presume makeAsyncRequest would somehow use them.)

Upvotes: 1

Related Questions