ในการทดสอบมอคค่าขณะที่เรียกใช้ฟังก์ชันอะซิงโครนัสวิธีหลีกเลี่ยงข้อผิดพลาดการหมดเวลา: เกินกำหนดเวลาเกิน 2000 มิลลิวินาที


200

ในแอปพลิเคชันโหนดของฉันฉันใช้มอคค่าเพื่อทดสอบรหัสของฉัน ในขณะที่เรียกฟังก์ชั่นอะซิงโครนัสจำนวนมากโดยใช้มอคค่าฉันจะได้รับข้อผิดพลาดการหมดเวลา ( Error: timeout of 2000ms exceeded.) ฉันจะแก้ไขปัญหานี้ได้อย่างไร

var module = require('../lib/myModule');
var should = require('chai').should();

describe('Testing Module', function() {

    it('Save Data', function(done) {

        this.timeout(15000);

        var data = {
            a: 'aa',
            b: 'bb'
        };

        module.save(data, function(err, res) {
            should.not.exist(err);
            done();
        });

    });


    it('Get Data By Id', function(done) {

        var id = "28ca9";

        module.get(id, function(err, res) {

            console.log(res);
            should.not.exist(err);
            done();
        });

    });

});

มันคือการทดสอบการรวม? ถึงเวลาสำหรับการทดสอบแล้ว - บางทีคุณควรพิจารณาสตับ - github.com/thlorenz/proxyquireอาจช่วยคุณได้
surui

@surui ขอบคุณฉันจะดูว่า
sachin

ฉันขอแนะนำให้ใช้สัญญาสำหรับเนื้อหาแบบอะซิงโครนัสและทดสอบแล้วมันเป็นเรื่องง่ายกับชัยตามคำสัญญา
Krym

คำตอบ:


344

คุณสามารถตั้งค่าการหมดเวลาเมื่อทำการทดสอบ:

mocha --timeout 15000

หรือคุณสามารถตั้งค่าการหมดเวลาสำหรับแต่ละชุดหรือทดสอบแต่ละรายการโดยทางโปรแกรม:

describe('...', function(){
  this.timeout(15000);

  it('...', function(done){
    this.timeout(15000);
    setTimeout(done, 15000);
  });
});

สำหรับข้อมูลเพิ่มเติมโปรดดูที่เอกสาร


3
-tรุ่นสั้นคือ options:{timeout:15000}ถ้าคุณใช้มอคค่าการทดสอบวิ่งมอคค่าจากงานที่ทำเสียงฮึดฮัดนี้ยังสนับสนุนในตัวเลือกของวัตถุ
svassr

5
FYI: ไม่ผ่านฟังก์ชั่นลูกศรไปที่ Mocha mochajs.org/#arrow-functions
c0ming

4
ฟังก์ชั่นลูกศรไม่ได้รับการสนับสนุนในลิงค์ด้านบน มันแค่บอกว่าคุณแค่ต้องรู้ว่าพวกเขาทำอะไรดังนั้นคุณจะไม่พลาดเมื่อต้องการเข้าถึงบริบท ฉันไม่ต้องการบริบทเพราะการพึ่งพาหมดเวลานั้นบอบบางและการทดสอบทั้งหมดของฉันทำงานในไม่กี่มิลลิวินาที แต่ฉันเจอปัญหาเดียวกันเมื่อใช้การทดสอบแบบ Sinon ยังคงใช้ lambdas 99% ของเวลา
oligofren

26
TypeError: this.timeout is not a functionเมื่อใช้"mocha": "^3.5.0"
Junior Mayhé

5
@adi คุณแน่ใจหรือไม่ว่าไม่ได้ใช้ฟังก์ชั่นลูกศร? เกี่ยวกับ async / รออยู่ในเอกสารดังนั้นควรทำงาน (และเป็นเช่นเดียวกับการใช้สัญญา) ฟังดูเหมือนคำถามอื่น
Andreas Hultgren

80

ฉันพบว่า "วิธีแก้ปัญหา" ของการเพิ่มระยะเวลาทำให้ชัดเจนว่าเกิดอะไรขึ้นที่นี่ซึ่งก็คือ

  1. การเรียกใช้รหัสและ / หรือเครือข่ายของคุณช้าเกินไป (ควรต่ำกว่า 100 ms เพื่อประสบการณ์การใช้งานที่ดี)
  2. การยืนยัน (การทดสอบ) ล้มเหลวและมีบางอย่างกลืนความผิดพลาดก่อนที่มอคค่าจะสามารถดำเนินการกับพวกเขาได้

คุณมักจะพบ # 2 เมื่อ Mocha ไม่ได้รับข้อผิดพลาดในการยืนยันจากการโทรกลับ นี่คือสาเหตุที่เกิดจากรหัสอื่น ๆ กลืนข้อยกเว้นขึ้นสแต็ค วิธีการที่เหมาะสมในการจัดการกับเรื่องนี้คือการแก้ไขรหัสและไม่กลืนข้อผิดพลาด

เมื่อรหัสภายนอกกลืนข้อผิดพลาดของคุณ

ในกรณีที่เป็นฟังก์ชั่นห้องสมุดที่คุณไม่สามารถแก้ไขได้คุณจะต้องตรวจสอบข้อผิดพลาดในการยืนยันและส่งต่อไปยัง Mocha ด้วยตัวคุณเอง คุณทำสิ่งนี้ด้วยการตัดการเรียกกลับยืนยันในบล็อกลอง / จับและส่งข้อยกเว้นใด ๆ ไปยังตัวจัดการที่ทำ

it('should not fail', function (done) { // Pass reference here!

  i_swallow_errors(function (err, result) {
    try { // boilerplate to be able to get the assert failures
      assert.ok(true);
      assert.equal(result, 'bar');
      done();
    } catch (error) {
      done(error);
    }
  });
});

แน่นอนสามารถสกัดแผ่นสำเร็จรูปนี้ไปยังฟังก์ชั่นยูทิลิตี้บางอย่างเพื่อให้การทดสอบดีขึ้น:

it('should not fail', function (done) { // Pass reference here!
    i_swallow_errors(handleError(done, function (err, result) {
        assert.equal(result, 'bar');
    }));
});

// reusable boilerplate to be able to get the assert failures
function handleError(done, fn) {
    try { 
        fn();
        done();
    } catch (error) {
        done(error);
    }
}

เร่งการทดสอบเครือข่าย

นอกเหนือจากนั้นฉันขอแนะนำให้คุณรับคำแนะนำในการเริ่มใช้สตับสำหรับการโทรผ่านเครือข่ายเพื่อทำการทดสอบผ่านโดยไม่ต้องพึ่งพาเครือข่ายที่ใช้งานได้ การใช้มอคค่าชัยและ Sinon การทดสอบอาจมีลักษณะเช่นนี้

describe('api tests normally involving network calls', function() {

    beforeEach: function () {
        this.xhr = sinon.useFakeXMLHttpRequest();
        var requests = this.requests = [];

        this.xhr.onCreate = function (xhr) {
            requests.push(xhr);
        };
    },

    afterEach: function () {
        this.xhr.restore();
    }


    it("should fetch comments from server", function () {
        var callback = sinon.spy();
        myLib.getCommentsFor("/some/article", callback);
        assertEquals(1, this.requests.length);

        this.requests[0].respond(200, { "Content-Type": "application/json" },
                                 '[{ "id": 12, "comment": "Hey there" }]');
        expect(callback.calledWith([{ id: 12, comment: "Hey there" }])).to.be.true;
    });

});

ดูเอกสารเพิ่มเติมของ Sinonniseสำหรับข้อมูลเพิ่มเติม


ฉันมีชุดการทดสอบขนาดใหญ่และฉันเพิ่งผ่านสัญญาทั้งหมดในรายละเอียดของฉันเพื่อให้แน่ใจว่าพวกเขากำลังโทรหาdone()ที่จุดสิ้นสุดของสัญญาและฉันได้ล้อเลียนเครือข่ายการโทรโดยใช้ Angular's $httpBackendแต่ไม่มีโชค การห่อสเปคทุกอันด้วย try-catch นั้นดูไม่เหมือนจริงมากนัก ข้อเสนอแนะอื่น ๆ ? ขอบคุณ!
Gustavo Matias

@GustavoMatias คุณจริง ๆ แล้วไม่ได้พูดถึงปัญหาของคุณแค่ระบุว่านี่ไม่ใช่ทางออกสำหรับสิ่งที่คุณมีปัญหา กรุณาทำอย่างละเอียด :-) การทดสอบของคุณไม่ได้ล้มเหลวเร็วพอหรือไม่? พวกเขาล้มเหลวในบางครั้ง แต่คุณต้องการที่จะรู้ว่าทำไม? ยากที่จะเดาว่าคุณตั้งใจจะทำอะไร
oligofren

สวัสดี @oligofren! นั่นไม่ใช่คำอธิบายที่ดีที่สุดแน่นอน มีคำอธิบายโดยละเอียดเพิ่มเติมเกี่ยวกับปัญหาของฉันที่นี่stackoverflow.com/questions/34510048/…ขอบคุณ!
Gustavo Matias

"โดยทั่วไปวิธีที่สะอาดที่สุด (แต่น่าเกลียดที่สุด) ในการจัดการกับปัญหานี้คือการห่อโค้ดของคุณด้วยการลอง / จับและส่งข้อยกเว้นใด ๆ ไปยังตัวจัดการที่กระทำ" ไม่นี่ไม่ใช่วิธีที่สะอาดที่สุด ไม่นานช็อต วิธีที่สะอาดที่สุดคือการเขียนโค้ดที่ไม่กลืนข้อยกเว้น ทุกครั้งที่ฉันเห็นใครบางคนบ่นว่ามอคค่าตรวจไม่พบการทดสอบที่ล้มเหลวนั่นเป็นเพราะมีบางอย่างกลืนข้อยกเว้น เพิ่มtry.... catch...ผลงานรอบข้อผิดพลาดในรหัสภายใต้การทดสอบมากกว่าการแก้ไขมัน
Louis

@ คุณอาจจะพูดถูกเกี่ยวกับคนที่นี่ แต่ฉันไม่สามารถตรวจสอบได้จากสีน้ำเงิน ต่อไปผู้คนมีปัญหากับมอคค่าดูเหมือนจะไม่สามารถจับข้อผิดพลาดได้และนี่เป็นวิธีจัดการกับมัน วิธีการที่กำหนดของคุณจะถือว่ารหัสการกลืนข้อผิดพลาดไม่ใช่ฟังก์ชั่นไลบรารีหรือคล้ายกันซึ่งในกรณีนี้จะไม่สามารถแก้ไขได้อย่างง่ายดาย
oligofren

7

สายเล็ก ๆ น้อย ๆ แต่บางคนสามารถใช้สิ่งนี้ได้ในอนาคต ... คุณสามารถเพิ่มการหมดเวลาการทดสอบของคุณได้โดยการอัปเดตสคริปต์ใน package.json ของคุณด้วยสิ่งต่อไปนี้:

"scripts": { "test": "test --timeout 10000" //Adjust to a value you need }

รันการทดสอบของคุณโดยใช้คำสั่ง test


ทำงานให้ฉัน! ขอบคุณ!
RayLoveless


1

สำหรับฉันแล้วปัญหาคือฟังก์ชันอธิบายซึ่งเมื่อให้ฟังก์ชันลูกศรทำให้มอคค่าพลาดการหมดเวลาและทำงานไม่สม่ำเสมอ (ใช้ ES6)

เนื่องจากไม่มีสัญญาถูกปฏิเสธฉันได้รับข้อผิดพลาดนี้ตลอดเวลาสำหรับการทดสอบต่าง ๆ ที่ล้มเหลวภายในบล็อกอธิบาย

ดังนั้นนี่คือลักษณะเมื่อทำงานไม่ถูกต้อง:

describe('test', () => { 
 assert(...)
})

และสิ่งนี้ทำงานโดยใช้ฟังก์ชั่นที่ไม่ระบุชื่อ

describe('test', function() { 
 assert(...)
})

หวังว่าจะช่วยใครบางคนการกำหนดค่าของฉันสำหรับข้างต้น: (nodejs: 8.4.0, npm: 5.3.0, mocha: 3.3.0)


0

ปัญหาของฉันไม่ได้ส่งการตอบกลับดังนั้นมันจึงหยุดทำงาน หากคุณกำลังใช้งานแบบด่วนตรวจสอบให้แน่ใจว่า res.send (data), res.json (data) หรือวิธีการ api ที่คุณต้องการใช้นั้นจะถูกดำเนินการสำหรับเส้นทางที่คุณกำลังทดสอบ


0

ตรวจสอบให้แน่ใจว่าได้แก้ไข / ปฏิเสธสัญญาที่ใช้ในกรณีทดสอบไม่ว่าจะเป็นสายลับหรือสตับให้แน่ใจว่าพวกเขาแก้ไข / ปฏิเสธ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.