使用 mocha js 测试依赖于前一个的异步函数

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

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

测试存储在 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);

so the tests shouldn't be executed in parallel.

声明一个测试是异步的只是告诉 Mocha 必须等待测试完成,而不是说它可以自由地并行进行 运行 测试。 Mocha 不会 运行 并行测试,无论它们是否同步。 因此您不必使用 async 来阻止 Mocha 执行某些操作一开始不做。 (如果你想并行测试 运行,你必须 添加 到你的测试设置中存在一些包。比如 this one。大概,他们修补了 Mocha 以添加并行能力。)

您应该只删除 async 内容,然后让您的 foreEach 回调直接调用 it

除此之外,您还设置了测试套件,以便一个测试取决于前一个测试的状态。通常,您应该编写 Mocha 测试,以便它们彼此独立。Mocha 的真正设计使得测试应该 运行 独立。例如,如果您使用 --grep 到 select 只是测试的一个子集。 Mocha 不会知道您的测试之间的依赖关系,如果 selected 测试依赖于未 selected 的测试,您将失败。通常,您想将测试依赖的任何东西放在 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 会以某种方式使用它们。 )