Mocha异步加载一组测试用例数据,然后动态创建测试用例

时间:2019-07-03 13:19:15

标签: node.js asynchronous mocha

我的问题:我想加载一组测试用例数据 (而不是测试用例本身),然后运行该组测试用例。加载数据和测试方法的所有操作都是异步的。


//testData.js
module.exports.loadTestData() {
    return new Promise(function(resolve, reject){
        var testDataArr = [];

        //do some async stuff and populate `testDataArr`
        setTimeout(1000, function(){
            testDataArr.push({
                "message": "test description 1",
                "data": "abcd" //data to pass to func
            })

            testDataArr.push({
                "message": "test description 1",
                "data": "abcd" //data to pass to func
            })

            resolve(testDataArr);
        })
    })
}

//myTests.test.js
const MyModule       = require('../index.js');
const TestDataHelper = require('./testData');
const chai           = require('chai');
const chaiAsPromised = require("chai-as-promised");

chai.use(chaiAsPromised);

const expect = chai.expect;

describe('#myTests', function(){
    describe('#aFunction', function(){
        describe('should fail', function(){
            var failureCases;

            before(async function(){
                 failureCases = await TestDataHelper.getTestData();
            })

            it('load test data', function(done){
                //dummy test to cause the "before" to run and load test data
            })

            failureCases.forEach(function(case){
                it(case.message, async function(){
                    await expect(MyModule.aFunction(case.data)).to.eventually.be.rejected;
                })
            })
        })
    })
})

以上是我最近一次尝试使其工作(即使用哑元函数来获取要在forEach之前加载的异步测试数据)的最新尝试,但是我仍然遇到以下错误:

TypeError: Cannot read property 'forEach' of undefined

这可能很明显,但是我遇到了鸡肉或鸡蛋问题,不确定如何解决。因为describe doesn't support returned promises,所以我还没有找到一种方法来将测试数据异步加载到数组中,然后在该数组上循环以动态生成测试用例。

我尝试过的其他一些解决方法(包括使用--delay标志):

///尝试的解决方法1(使用--delay标志)

var failureCases;

TestDataHelper.getTestData().then(function(arr){
    failureCases = arr;

    run();
})

describe('#myTests', function(){
    describe('#aFunction', function(){
        describe('should fail', function(){
            failureCases.forEach(function(case){
                it(case.message, async function(){
                    await expect(MyModule.aFunction(case.data)).to.eventually.be.rejected;
                })
            })
        })
    })
})

//mocha --delay still produces "Cannot read property 'forEach' of undefined" error

尝试的解决方法2(在异步测试用例中加载数据,然后动态创建更多内容)

describe('#myTests', function(){
    describe('#aFunction', function(){
        describe('should fail', function(){
            it('load test data', async function(done){
                var failureCases = await TestDataHelper.getTestData();

                failureCases.forEach(function(case){
                    it(case.message, async function(){
                        await expect(MyModule.aFunction(case.data)).to.eventually.be.rejected;
                    })
                })
            })
        })
    })
})

在这种解决方法中,mocha不会产生错误,但是它似乎并没有真正运行动态生成的测试,因为我仅获得以下输出:

> mocha

#myTests
  #aFunction
    should fail
      load test data ✓

2 个答案:

答案 0 :(得分:0)

弄清楚了。如果正确使用,请使用--delay/run()。 `描述实际上需要在异步方法完成之后的同一块中执行。

回到我的“尝试解决方法#1”,它看起来应该像这样:


> mocha --delay

//myTests.test.js
TestDataHelper.getTestData().then(function(failureCases){

    describe('#myTests', function(){
        describe('#aFunction', function(){
            describe('should fail', function(){
                failureCases.forEach(function(case){
                    it(case.message, async function(){
                        await expect(MyModule.aFunction(case.data)).to.eventually.be.rejected;
                    })
                })
            })
        })
    })

    run();
})

答案 1 :(得分:0)

我知道这是一个有点老的问题,但是不得不使用--delay之类的选项似乎并不适合我,而我的一项测试也遇到了同样的问题。我通过简单地将测试用例包装在自己的封闭中而使我工作。我认为以下内容适合您的情况。

describe('#myTests', function(){
    describe('#aFunction', function(){
        describe('should fail', function(){
            function itArray(case) {
                it(case.message, async function(){
                    await expect(MyModule.aFunction(case.data)).to.eventually.be.rejected;
                })
            }
            failureCases.forEach(function(case){
               itArray(case);
            })
        })
    })
})