我是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循环遍历整个数组,所有测试都不起作用,但是如果我迭代直到最后一个索引,则会起作用。有人可以为我解决这个问题吗?
答案 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_array
和against
,那将是一个真正的维护问题。很难看到这些,并确保正确的值匹配。
相反,将所有内容放入一个数组中,其中每个数组元素都包含两个测试值:
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}