[英]Using a for loop in a Mocha Test
我是 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 循環遍歷整個數組,為什么所有測試都不起作用,但如果我迭代到最后一個索引就可以了。 有人可以幫我解決這個問題嗎?
您的代碼可能是同步的,但 mocha 將其稱為異步。 意思是:你的 it 描述是同步解析的,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);
});
}
});
});
所以,我很困惑,如果 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);
}
})
})
這樣,傳遞給it()
每個callback
都可以訪問數組,而不會在測試時間之前刪除或更改它們。
我根本不懂摩卡咖啡,所以我會聽從約翰內斯的專家建議。
不過我確實有一些其他的建議給你。
首先,這將是一個真正令人頭疼的維護問題,兩個數組並行運行,例如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 的代碼為起點,我將其更改為:
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
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}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.