簡體   English   中英

在 Mocha 測試中使用 for 循環

[英]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_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 的代碼為起點,我將其更改為:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM