测试异步函数,这些函数依赖于前一个函数和mochajs

时间:2015-12-04 09:14:22

标签: javascript mocha

我正在为服务器编写一组测试。 基本上有预定义的请求和每个请求的预期答案。

测试存储在json文件中,因此我可以根据需要将其扩展。

一些测试依赖于前面测试的两个ID,因此测试不应该并行执行。要归档我正在使用waterfall function of the async library,所以我能够将参数传递给下一个函数。

问题是,当我迭代这个测试数组时,我正在调用it(testname, function(done){...})。在这个函数中,我执行请求并将响应与预期答案进行比较。之后我调用done函数,以便mochajs知道测试已经完成。

当我开始测试时,第一个被执行,但没有更多。

对我而言,mochajs认为当前没有其他测试任务正在运行,因此它会停止脚本。

这是测试:

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);

1 个答案:

答案 0 :(得分:1)

  

所以测试不应该并行执行。

声明测试是异步的只是告诉Mocha必须等待测试完成,而不是它可以自由地并行运行测试。 Mocha不会并行运行测试,无论它们是否同步。因此您不必使用async来阻止Mocha做一些它不会做的事情。 (如果您希望并行运行测试,则必须添加到您的测试设置中。如this one。可能,他们会修补Mocha以添加并行功能。)

您应该删除async内容,并直接拨打foreEach回拨电话it

除此之外,您已设置测试套件,以便一次测试取决于先前测试的状态。通常,你应该编写你的Mocha测试,以便它们彼此独立。 Mocha的设计确实应该让测试独立运行。例如,如果您使用--grep仅选择一部分测试。摩卡不知道您的测试之间的依赖关系,如果所选的测试依赖于未选择的测试,您将会失败。通常,您希望在beforebeforeEach挂钩中放置测试所依赖的任何内容。

如果您处于这样繁重的情况,您可以将状态保持在更高的范围内。我不想让它全球化,所以我把所有内容放在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();
        });
    });
});

(我不会在你的问题中看到idX变量是如何用来发出新请求所以我上面的代码没有显示它。我认为makeAsyncRequest会以某种方式使用它们。 )