在Mocha测试中使用for循环

时间:2016-10-18 07:11:50

标签: javascript node.js for-loop mocha

我是mocha的新手,我想尝试使用for循环来创建测试用例。我想测试一个我所做的功能,它输入标准的12小时时间,然后输出到24小时的军事时间。这就是它的样子。

exports.main = function(time) {
var hr = parseInt(time.substr(0,2));
var period = time.substr(8,10);
if (period == 'AM' && hr == 12) {
    hr = '0';
}
if (period == 'PM' && hr < 12) {
           hr += 12;
}
    hr.toString();
    if (hr < 10) {
        hr = '0' + hr;
    }
 return time = time.replace(/^\d{2}/g, hr).substr(0,8);

}

为了在mocha中测试我的函数,我有两个数组,一个数组保持标准时间,另一个数组保存相应的预期输出。我想迭代它们并为每次迭代生成一个测试用例并测试我的函数。

test_array = ["12:00:00AM", "01:00:00AM", "02:00:00AM", "03:00:00AM", "04:00:00AM",
"05:00:00AM", "06:00:00AM", "07:00:00AM", "08:00:00AM", "09:00:00AM",
"10:00:00AM", "11:00:00AM", "12:00:00PM", "01:00:00PM", "02:00:00PM",
"03:00:00PM", "04:00:00PM", "05:00:00PM", "06:00:00PM", "07:00:00PM",
"08:00:00PM", "09:00:00PM", "10:00:00PM", "11:00:00PM"];

against = ["00:00:00", "01:00:00", "02:00:00", "03:00:00", "04:00:00",
"05:00:00", "06:00:00", "07:00:00", "08:00:00", "09:00:00", "10:00:00",
"11:00:00", "12:00:00", "13:00:00", "14:00:00", "15:00:00", "16:00:00",
"17:00:00", "18:00:00", "19:00:00", "20:00:00", "21:00:00", "22:00:00",
"23:00:00"]

这是我的测试脚本的样子:

var converter = require('../modules/time.js');
describe('Time Converter', function() {
 describe('main()', function() {
  for(i = 0; i < 24; i++) {
   it(test_array[i]  + ' should convert to ' + against[i], function() {
   var test = converter.main(test_array[i]);
   assert.equal(test, against[i]);
   });
  }
 });
});

以下是测试结果:

0 passing (23ms)
24 failing

1) Time Converter main() 12:00:00AM should convert to 00:00:00:
 TypeError: Cannot read property 'substr' of undefined
  at Object.exports.main (app/modules/time.js:43:27)
  at Context.<anonymous> (app/test/test.js:35:26)

2) - 24) has the same result:

24) Time Converter main() 11:00:00PM should convert to 23:00:00:
 TypeError: Cannot read property 'substr' of undefined
  at Object.exports.main (app/modules/time.js:43:27)
  at Context.<anonymous> (app/test/test.js:35:26)

但是当我将for循环更改为

for(i = 0; i < 23; i++)

所有测试都通过,但自然不会测试最后一个测试用例。

Time Converter
main()
  ✓ 12:00:00AM should convert to 00:00:00
  ✓ 01:00:00AM should convert to 01:00:00
  ✓ 02:00:00AM should convert to 02:00:00
  ✓ 03:00:00AM should convert to 03:00:00
  ✓ 04:00:00AM should convert to 04:00:00
  ✓ 05:00:00AM should convert to 05:00:00
  ✓ 06:00:00AM should convert to 06:00:00
  ✓ 07:00:00AM should convert to 07:00:00
  ✓ 08:00:00AM should convert to 08:00:00
  ✓ 09:00:00AM should convert to 09:00:00
  ✓ 10:00:00AM should convert to 10:00:00
  ✓ 11:00:00AM should convert to 11:00:00
  ✓ 12:00:00PM should convert to 12:00:00
  ✓ 01:00:00PM should convert to 13:00:00
  ✓ 02:00:00PM should convert to 14:00:00
  ✓ 03:00:00PM should convert to 15:00:00
  ✓ 04:00:00PM should convert to 16:00:00
  ✓ 05:00:00PM should convert to 17:00:00
  ✓ 06:00:00PM should convert to 18:00:00
  ✓ 07:00:00PM should convert to 19:00:00
  ✓ 08:00:00PM should convert to 20:00:00
  ✓ 09:00:00PM should convert to 21:00:00
  ✓ 10:00:00PM should convert to 22:00:00
  23 passing (14ms)

然而,当我自己测试最后一个测试用例时,它会通过。

✓ 11:00:00PMshould convert to 23:00:00

所以,我很困惑,为什么如果for循环遍历整个数组,所有测试都不起作用,但是如果我迭代直到最后一个索引,则会起作用。有人可以为我解决这个问题吗?

4 个答案:

答案 0 :(得分:9)

您的代码可能是同步的,但是mocha将其称为异步。意思是:你的描述被解析同步,mocha存储这些信息并在其自己的上下文中运行每个测试。这是异步的。要使其工作,您必须使用函数创建一个闭包:

var converter = require('../modules/time.js');
// outside the loop:
function itShouldTestArray(i) {
   // i is now within the function scope and won't change anymore
   it(test_array[i]  + ' should convert to ' + against[i], function() {
   var test = converter.main(test_array[i]);
   assert.equal(test, against[i]);
}
describe('Time Converter', function() {
 describe('main()', function() {
  for(i = 0; i < 24; i++) {
   itShouldTestArray(i);
   });
  }
 });
});

答案 1 :(得分:1)

  

所以,我很困惑为什么所有的测试都不能用于for循环   遍历整个数组,但如果我迭代直到   最后一个指数有人可以帮我解决这个问题吗?

这可能是由Mocha进行的异步测试导致的一个非常难以调试的问题。似乎将i从23更改为24会导致您的数组在执行测试之前被删除,从而提供错误消息:

 TypeError: Cannot read property 'substr' of undefined

通过在闭包内分配值,可以在测试时间之前避免删除数组:

var converter = require('../modules/time.js');

describe('Time Converter', function() {
  describe('main()', function() {

       test_array = // insert array inside closure;
       against = //insert array inside closure;

       callback = function () {

        var test = converter.main (test_array[i]);
        assert.equal(test, against[i]);
       }

       for(i = 0; i < 24; i++) {

          it(test_array[i]  + ' should convert to ' + against[i], callback);
        }
      })
    })

这样,传递给callback的每个it()都可以访问数组,而不会在测试时间之前删除或更改它们。

答案 2 :(得分:0)

我根本不了解摩卡,所以我会按照约翰内斯的说法去做。专家建议。

我确实有一些其他的建议。

首先,如果有两个并行运行的阵列,如test_arrayagainst,那将是一个真正的维护问题。很难看到这些,并确保正确的值匹配。

相反,将所有内容放入一个数组中,其中每个数组元素都包含两个测试值:

var tests = [
    '12:00:00AM = 00:00:00',
    '01:00:00AM = 01:00:00',
    '02:00:00AM = 02:00:00',
    '03:00:00AM = 03:00:00',
    '04:00:00AM = 04:00:00',
    '05:00:00AM = 05:00:00',
    '06:00:00AM = 06:00:00',
    '07:00:00AM = 07:00:00',
    '08:00:00AM = 08:00:00',
    '09:00:00AM = 09:00:00',
    '10:00:00AM = 10:00:00',
    '11:00:00AM = 11:00:00',
    '12:00:00PM = 12:00:00',
    '01:00:00PM = 13:00:00',
    '02:00:00PM = 14:00:00',
    '03:00:00PM = 15:00:00',
    '04:00:00PM = 16:00:00',
    '05:00:00PM = 17:00:00',
    '06:00:00PM = 18:00:00',
    '07:00:00PM = 19:00:00',
    '08:00:00PM = 20:00:00',
    '09:00:00PM = 21:00:00',
    '10:00:00PM = 22:00:00',
    '11:00:00PM = 23:00:00',
];

您可以在代码中使用split()来分隔每个数组元素中的两个值。

接下来,从不for循环中硬编码数组长度。相反,如果数组在上面的示例中名为test,请在循环中使用i < test.length。现在,如果添加或删除条目,循环仍将具有正确的长度。

但是,我根本不会在这里使用for循环。您可以使用forEach数组方法获得更清晰的代码。

以Johannes&#39;代码作为起点,我将其改为:

function itShouldTestTimes( test ) {
    var times = test.split( ' = ' );
    var time12 = times[0], time24 = times[1];
    it( time12 + ' should convert to ' + time24, function() {
        var result = converter.main( time12 );
        assert.equal( result, time24 );
    });
}

describe( 'Time Converter', function() {
    describe( 'main()', function() {
        tests.forEach( itShouldTestTimes );
    });
});

答案 3 :(得分:0)

1)BatchTest.js

const assert = require('chai').assert;
const fileOperations = require('../UDRServer/Utility/FileOperations');
var testResultFileName = "TestResult.json";

var data = fileOperations.readFile(testResultFileName);
//console.log(data);

var jsons = data.split('\n');


function runTest(obj) {
    describe(obj.name + " Test", function () {
        it("Expexted Value " + obj.expectedStatus, function (done) {

            assert.equal(obj.expectedStatus, obj.actualStatus);
            if (obj.expectedCause != 'null') {
                assert.equal(obj.expectedCause, obj.actualCause);
            }
            done();
        })

    })
}


describe("Main", function () {
    for (let i = 0; i < jsons.length - 1; i++) {
        var obj = JSON.parse(jsons[i]);
        runTest(obj);
    }
});

2)FileOperations.js

var readFile = function(filename){
    return fs.readFileSync(filename).toString();
}

3)TestResult.json文件

{"actualStatus":403,"actualCause":"false","name":"test1","expectedCause":"false","expectedStatus":400}
{"actualStatus":0,"actualCause":"true","name":"test2","expectedCause":"false","expectedStatus":400}
{"actualStatus":400,"actualCause":"false","name":"test3","expectedCause":"false","expectedStatus":400}
{"actualStatus":200,"actualCause":"true","name":"test4","expectedCause":"false","expectedStatus":200}
相关问题