비동기 함수를 호출하는 동안 mocha 테스트에서 시간 초과 오류를 피하는 방법 : 시간 초과 2000ms 초과


200

내 노드 응용 프로그램에서 mocha를 사용하여 코드를 테스트하고 있습니다. mocha를 사용하여 많은 비동기 함수를 호출하는 동안 시간 초과 오류 ( 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

비동기식에 대한 약속을 사용하고 테스트하는 것이 좋습니다. 약속 대로 Chai를 사용
Krym

답변:


344

테스트를 실행할 때 시간 초과를 설정할 수 있습니다.

mocha --timeout 15000

또는 프로그래밍 방식으로 각 제품군 또는 각 테스트에 대한 시간 초과를 설정할 수 있습니다.

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

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

자세한 내용은 문서를 참조하십시오 .


3
더 짧은 버전은 -t입니다. grunt 태스크에서 mocha-test를 사용하여 mocha를 실행하는 경우 옵션 object에서도 지원됩니다 options:{timeout:15000}.
svassr

5
참고 : 화살표 기능을 Mocha에 전달하는 것은 권장되지 않습니다. mochajs.org/#arrow-functions
c0ming

4
위의 링크에서 화살표 기능은 권장되지 않습니다. 단지 그들이하는 일을 알아야하므로 컨텍스트에 액세스해야 할 때 망치지 않아도됩니다. 시간 초과에 의존하는 것은 깨지기 쉽고 컨텍스트가 필요하지 않으며 모든 테스트가 몇 ms 내에 실행되지만 sinon-test를 사용할 때 동일한 문제가 발생합니다. 여전히 람다를 99 % 사용하십시오.
oligofren 2016 년

26
TypeError: this.timeout is not a function를 사용할 때"mocha": "^3.5.0"
Junior Mayhé

5
@adi 화살표 기능을 사용하지 않습니까? async / await에 대해서는 문서에 있으므로 작동해야합니다 (약속을 사용하는 것과 같습니다). 그러나 다른 질문처럼 들립니다.
Andreas Hultgren

80

시간 초과를 늘리는 "솔루션"이 실제로 진행중인 작업을 모호하게합니다.

  1. 코드 및 / 또는 네트워크 호출 속도가 너무 느립니다 (사용자 경험을 좋게하려면 100ms 미만이어야 함)
  2. 단언 (테스트)이 실패하고 Mocha가 조치를 취하기 전에 오류가 발생했습니다.

일반적으로 Mocha가 콜백에서 어설 션 오류를받지 못하면 # 2가 발생합니다. 이것은 다른 코드가 스택을 더 이상 예외를 삼키기 때문에 발생합니다. 이를 처리하는 올바른 방법은 코드를 수정하고 오류를 삼키지 않는 것 입니다.

외부 코드가 오류를 삼킬 때

수정할 수없는 라이브러리 함수 인 경우 어설 션 오류를 잡아서 Mocha에 직접 전달해야합니다. 어설 션 콜백을 try / catch 블록에 래핑하고 예외를 done 처리기에 전달하면됩니다.

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

네트워크 테스트 속도 향상

그 외에는 작동하는 네트워크에 의존하지 않고 테스트를 통과하기 위해 네트워크 호출에 테스트 스텁을 사용하기 시작하는 것에 대한 조언을 얻는 것이 좋습니다. Mocha, Chai 및 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;
    });

});

자세한 내용은 Sinon의 nise문서 를 참조하십시오.


나는 거대한 테스트 모음을 가지고 있으며 약속 done()의 끝에서 모두 호출 되고 있는지 확인하기 위해 사양의 모든 약속을 겪었으며 Angular의을 사용하여 네트워크 호출을 이미 조롱하고 $httpBackend있지만 운이 없습니다. 모든 단일 스펙을 try-catch로 감싸는 것은 실용적이지 않습니다. 다른 제안? 감사!
구스타보 마티아스

@GustavoMatias 당신은 실제로 당신의 문제가 무엇인지 언급하지 않았으며, 이것이 당신이 문제가있는 것에 대한 해결책이 아니라고 언급했습니다. 정교하게 수행하십시오 :-) 테스트가 충분히 실패하지 않습니까? 그들은 때때로 실패하고 있지만, 왜 그런지 알고 싶습니까? 달성하려는 것을 추측하기가 어렵습니다.
oligofren

안녕하세요 @oligofren! 그것은 실제로 최고의 설명이 아니 었습니다. 내 문제에 대한 자세한 설명이 여기 있습니다. stackoverflow.com/questions/34510048/… 감사합니다!
구스타보 마티아스

"일반적으로이 문제를 처리하는 가장 깨끗한 방법 (그러나 가장 추악한 방법)은 코드를 try / catch로 감싸고 예외를 done 처리기에 전달하는 것입니다." 아니요, 이것은 가장 깨끗한 방법이 아닙니다. 멀리서도 아닙니다. 가장 깨끗한 방법은 예외를 삼키지 않는 코드를 작성하는 것입니다. 내가 볼 때마다 모카가 실패한 테스트를 감지하지 못했다고 불평하는 것은 예외를 삼키는 것이 있었기 때문입니다. 추가 try.... catch...작품 보다는 테스트중인 코드에서 버그를 수정 그것.
Louis

@Louis 당신은 아마도 이유에 대해 옳을 지 모르지만, 나는 그것을 파란색으로 확인할 수 없습니다. 어쨌든, 사람들은 모카에 문제가 겉으로는 몇 가지 오류를 잡을 수없는 것, 그리고이 그것을 처리하는 방법입니다. 주어진 접근 방식은 오류를 삼키는 코드가 라이브러리 기능이나 이와 유사한 것이 아니라고 가정합니다.이 경우 너무 쉽게 해결할 수 없습니다.
oligofren

7

조금 늦었지만 나중에 이것을 사용할 수 있습니다 ... package.json의 스크립트를 다음과 같이 업데이트하여 테스트 시간 초과를 늘릴 수 있습니다.

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

명령을 사용하여 테스트를 실행하십시오. test


나를 위해 일했다! 감사합니다!
RayLoveless

5

화살표 기능을 사용하는 경우 :

it('should do something', async () => {
  // do your testing
}).timeout(15000)

1

나에게 문제는 실제로 화살표 기능을 제공 할 때 모카가 시간 초과를 놓치고 일관되게 동작하지 않는 describe 함수였습니다. (ES6 사용)

약속이 거부되지 않았기 때문에 describe 블록 내에서 실패한 다른 테스트에서 항상이 오류가 발생했습니다.

제대로 작동하지 않을 때의 모습입니다.

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

그리고 이것은 익명 함수를 사용하여 작동합니다

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

누군가에게 도움이되기를 바랍니다. (nodejs : 8.4.0, npm : 5.3.0, mocha : 3.3.0)


0

내 문제는 응답을 다시 보내지 않아서 중단되었습니다. express를 사용하는 경우 res.send (data), res.json (data) 또는 사용하려는 API 메소드가 테스트중인 경로에 대해 실행되는지 확인하십시오.


0

테스트 사례에 사용 된 약속을 해결 / 거부해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.