简体   繁体   English

在 Mocha 测试中使用 for 循环

[英]Using a for loop in a Mocha Test

I'm new to mocha, and I wanted to try using a for loop to create test cases.我是 mocha 新手,我想尝试使用 for 循环来创建测试用例。 I want to test a function that I've made that takes an input of standard 12 hour time, and outputs it into 24 hour military time.我想测试我制作的一个函数,该函数输入标准 12 小时时间,并将其输出为 24 小时军用时间。 This is what it looks like.这就是它的样子。

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

}

To test my function in mocha, I have two arrays, one array holds the standard times and the other holds the corresponding expected output.为了在 mocha 中测试我的函数,我有两个数组,一个数组保存标准时间,另一个保存相应的预期输出。 I want to iterate through them and produce a test case for each iteration and test my function.我想遍历它们并为每次迭代生成一个测试用例并测试我的函数。

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"]

This is what my test script looks like:这是我的测试脚本的样子:

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

The following is the results of the tests:以下是测试结果:

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)

However when I change the for loop to但是,当我将 for 循环更改为

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

All the tests pass except, naturally it doesn't test the last test case.所有测试都通过了,当然它不会测试最后一个测试用例。

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)

However when I test the last test case by itself, it passes.但是,当我单独测试最后一个测试用例时,它通过了。

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

So, I'm confused as to why all the tests don't work if the for loop iterates through the whole array, but works if I iterate up until the last index.所以,我很困惑,如果 for 循环遍历整个数组,为什么所有测试都不起作用,但如果我迭代到最后一个索引就可以了。 Can someone clear this up for me?有人可以帮我解决这个问题吗?

Your code may be sync, but mocha calls it it async.您的代码可能是同步的,但 mocha 将其称为异步。 Means: your it descriptions are parsed sync, mocha stores this information and runs every test in it's own context.意思是:你的 it 描述是同步解析的,mocha 存储这些信息并在它自己的上下文中运行每个测试。 This is async.这是异步的。 To make this work, you have to create a closure with a function:要完成这项工作,您必须创建一个带有函数的闭包:

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

So, I'm confused as to why all the tests don't work if the for loop iterates through the whole array, but works if I iterate up until the last index.所以,我很困惑,如果 for 循环遍历整个数组,为什么所有测试都不起作用,但如果我迭代到最后一个索引就可以了。 Can someone clear this up for me?有人可以帮我解决这个问题吗?

This is probably a very-hard-to-debug-problem caused by the asynchronous testing conducted by Mocha.这可能是由 Mocha 进行的异步测试引起的一个非常难以调试的问题。 It seems like that changing i from 23 to 24 somehow results in your arrays being deleted before the tests are conducted, confer the error message:似乎将i从 23 更改为 24 会以某种方式导致您的数组在进行测试之前被删除,请提供错误消息:

 TypeError: Cannot read property 'substr' of undefined

You can avoid this deletion of the arrays before testing time by assigning their values inside a closure:您可以通过在闭包中分配数组的值来避免在测试时间之前删除数组:

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

This way each callback passed to it() will have access to the arrays without any possibility of them being deleted or altered before testing time.这样,传递给it()每个callback都可以访问数组,而不会在测试时间之前删除或更改它们。

I don't know mocha at all, so I will defer to Johannes' expert advice on that.我根本不懂摩卡咖啡,所以我会听从约翰内斯的专家建议。

I do have some other suggestions for you though.不过我确实有一些其他的建议给你。

First, it will be a real maintenance headache having two arrays running in parallel like test_array and against .首先,这将是一个真正令人头疼的维护问题,两个数组并行运行,例如test_arrayagainst It's hard to look at those and be sure the right values are matched up.很难查看这些并确保匹配正确的值。

Instead, put everything into a single array, where each array element contains both test values:相反,将所有内容放入一个数组中,其中每个数组元素都包含两个测试值:

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',
];

You can use split() in your code to separate the two values in each array element.您可以在代码中使用split()来分隔每个数组元素中的两个值。

Next, never hard code an array length in a for loop.接下来,永远不要for循环中对数组长度进行硬编码。 Instead, if the array is named test as in my example above, use i < test.length in the loop.相反,如果数组如我上面的示例一样命名为test ,则在循环中使用i < test.length Now if you add or remove entries, the loop will still have the correct length.现在,如果您添加或删除条目,循环仍将具有正确的长度。

However, I wouldn't use a for loop here at all.但是,我根本不会在这里使用for循环。 You can get cleaner code by using the forEach array method.您可以使用forEach数组方法获得更清晰的代码。

Taking Johannes' code as a starting point, I would change it to:以 Johannes 的代码为起点,我将其更改为:

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

1) BatchTest.js 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 2) FileOperations.js

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

3) TestResult.json file 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}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM