jest.setTimeout에 의해 지정된 5000ms 시간 초과 내에 비동기 콜백이 호출되지 않았습니다.


238

puppeteer와 jest를 사용하여 프런트 엔드 테스트를 실행하고 있습니다.

내 테스트는 다음과 같습니다.

describe("Profile Tab Exists and Clickable: /settings/user", () => {
    test(`Assert that you can click the profile tab`, async () => {
      await page.waitForSelector(PROFILE.TAB);
      await page.click(PROFILE.TAB);
    }, 30000);
});

때로는 테스트를 실행할 때 모든 것이 예상대로 작동합니다. 다른 경우에는 오류가 발생합니다.

Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.

      at node_modules/jest-jasmine2/build/queue_runner.js:68:21
      at Timeout.callback [as _onTimeout] (node_modules/jsdom/lib/jsdom/browser/Window.js:633:19)

다음과 같은 이유로 이상합니다.

  1. 시간 초과를 30000으로 지정했습니다.

  2. 이 오류가 발생하는지 여부는 매우 무작위로 보입니다.

왜 이런 일이 일어나는지 추측 할 수 있습니까?


어느 라인이 타임 아웃되고 있습니까?
lloyd

@Asool GitHub 리포지토리를 제공해 주시겠습니까? 솔루션을보다 쉽고 빠르게 제공 할 수 있습니다. :)
Shishir Anshuman

@Asool, 내가 게시 한 답변에 대한 의견
Tarun Lalwani

1
실제로 30000ms 동안 테스트가 실패하지만 jest의 오류는 단순히 전달 한 값을 포함하지 않습니까? 즉, 0ms 시간을 초과하면 jest 오류가 변경됩니까?
Nirit Levi

테스트를 디버깅 할 때이 오류가 발생했습니다. 중단 점에서 정지하면이 오류가 발생했습니다.
Neets

답변:


259

따라서 여기서 지정하는 시간 초과는 기본 시간 초과보다 짧아야합니다.

기본 시간 초과는 5000이고 기본적으로 프레임 워크는 jasmine입니다 jest. 테스트 내부에 시간 초과를 추가하여 추가 할 수 있습니다

jest.setTimeout(30000);

그러나 이것은 테스트에만 해당됩니다. 또는 프레임 워크에 대한 구성 파일을 설정할 수 있습니다.

https://facebook.github.io/jest/docs/en/configuration.html#setuptestframeworkscriptfile-string

// jest.config.js
module.exports = {
  // setupTestFrameworkScriptFile has been deprecated in
  // favor of setupFilesAfterEnv in jest 24
  setupFilesAfterEnv: ['./jest.setup.js']
}

// jest.setup.js
jest.setTimeout(30000)

이 스레드도 참조

https://github.com/facebook/jest/issues/5055

https://github.com/facebook/jest/issues/652

PS 철자 오류 setupFilesAfterEnv(예 :) setupFileAfterEnv도 같은 오류가 발생합니다.


2
Jest 문서를 통해 쉽게 찾을 수없는 질문에 답변 해 주셔서 감사합니다.
HartleySan

21
이 날 도움으로, 그것은이 협조 할 수 있습니다 setupTestFrameworkScriptFile로 대체되었습니다 setupFilesAfterEnv때문에이되고,setupFilesAfterEnv: ["./jest.setup.js"]
맥심 Geerinck

1
나는 또한 jest.setTimeout(10000)엣지 케이스에 대한 단일 테스트에 추가 될 수 있으므로 전체 구성을 변경할 필요가 없다는 것을 알았습니다.)
James

내가 뭔가를 그리워해야하지만 추가 할 경우 jest.setTimeout(30000);jest.config.js내가 할 "오류 ReferenceError가 : 농담이 정의되어 있지 않습니다." 추가하려고했지만 const jest = require("jest");"TypeError : jest.setTimeout is a function"이 표시됩니다.
장 폴

죄송합니다. 너무 빨리 읽었습니다.에있는 setupFilesAfterEnv인수 jest.config.jsjest.setTimeout(30000)옵션 을 넣을 다른 파일을 가리켜 야합니다 . 우리가 이것을 구성 할 수있는 것이 좋지만 조금 복잡해 보입니다.
장 폴

64

async/await테스트에서 비동기 일 때 호출해야합니다 .

describe("Profile Tab Exists and Clickable: /settings/user", () => {
    test(`Assert that you can click the profile tab`, async (done) => {
        await page.waitForSelector(PROFILE.TAB);
        await page.click(PROFILE.TAB);
        done();
    }, 30000);
});

24
done비동기 기능을 사용해야하는 이유는 무엇 입니까? 우리는 단순히 약속이나 정의되지 않은 것을 반환하지 않습니까?
Charlie Schliesser

2
아니요, 정확하지 않습니다. 약속을 기다리고 있거나 그냥 반환 할 수 있기 때문에 done ()을 호출 할 필요가 없습니다 page.click. done ()은 적어도 필자의 경우 주로 콜백 테스트를 위해 사용됩니다.
저스틴

2
고맙습니다 done. 필요하지 않은 콜백을 제거했습니다 .
슈뢰딩거의 코드

26
이것은 원래 질문과 동일한 코드가 아닌가?
Joe

1
done콜백에 매개 변수 ( 이 경우 이름 )가 있으면이 매개 변수가 호출 될 때까지 Jest가 대기합니다. 사용하지 않더라도 그 존재는 중요합니다.
vaughan

54

Jest가 발전함에 따라이 질문에 대한 답변이 변경되었습니다. 현재 답변 (2019 년 3 월) :

  1. 에 세 번째 매개 변수를 추가하여 개별 테스트의 시간 초과를 무시할 수 있습니다 it. 즉.it('runs slow', () => {...}, 9999)

  2. 을 사용하여 기본값을 변경할 수 있습니다 jest.setTimeout. 이것을하기 위해:

 // config
   "setupFilesAfterEnv": [  // NOT setupFiles
     "./src/jest/defaultTimeout.js"
   ],

// File: src/jest/defaultTimeout.js
/* global jest */
jest.setTimeout(1000)
  1. 다른 사람들이 지적했듯이 이것과 직접 관련 done이없는 것은 async / await 접근법에는 필요하지 않습니다.

5
이것은보다 현대적인 버전입니다
jonashdown

23

3000테스트 시간이 초과 되어도 여전히 (임의로) 실패하는 경우가 있습니다.

Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.

@Tarun의 훌륭한 답변 덕분에 많은 테스트를 해결하는 가장 짧은 방법은 다음과 같습니다.

describe('puppeteer tests', () => {
  beforeEach(() => {
    jest.setTimeout(10000);
  });

  test('best jest test fest', async () => {
    // blah
  });
});

9
jest.setTimeout()inside beforeEach호출 할 필요는 없으며 한 번만 호출하면 모든 테스트에 충분합니다.
Marcos Pereira

19

이것은 비교적 새로운 업데이트이지만 훨씬 간단합니다. jest 24.9.0 이상을 사용하는 경우 testTimeout구성에 추가 할 수 있습니다 .

// in jest.config.js
module.exports = {
  testTimeout: 30000
}

17

done();콜백 을 호출 해야합니다. 그렇지 않으면 단순히 테스트를 통과하지 않습니다.

beforeAll((done /* call it or remove it*/) => {
  done(); // calling it
});

done () 콜백이있는 다른 모든 함수에 적용됩니다.


1
@ZenVentzi라고 언급했습니다. 감사 :)!
ivanleoncz

11

jest 24.9+의 경우 다음을 추가하여 명령 줄에서 시간 초과를 설정할 수도 있습니다 --testTimeout

다음은 문서 에서 발췌 한 것입니다.

--testTimeout=<number>
Default timeout of a test in milliseconds. Default value: 5000.

3

나는 최근에 다른 이유로이 문제에 부딪쳤다 :을 사용하여 동기식으로 일부 테스트를 실행하고 있었고 jest -i시간이 초과되었습니다. 어떤 추론 이건간에 jest --runInBand( -i별칭 이더라도 ) 사용하여 동일한 테스트를 실행 해도 시간이 초과되지 않습니다.

어쩌면 이것은 누군가를 도울 것입니다 ¯\_(:/)_/¯


1

시간 초과 문제는 네트워크 속도가 느리거나를 사용하여 많은 네트워크 호출을 수행 할 때 발생합니다 await. 이러한 시나리오는 기본 시간 초과 (예 : 5000ms)를 초과합니다. 시간 종료 오류를 피하려면 시간 종료를 지원하는 글로벌의 시간 종료를 늘리십시오. 전역 목록과 서명은 여기 에서 찾을 수 있습니다 .
농담 24.9


1
// in jest.setup.js
jest.setTimeout(30000)

Jest <= 23 인 경우 :

// in jest.config.js
module.exports = {
  setupTestFrameworkScriptFile: './jest.setup.js'
}

Jest> 23 인 경우 :

// in jest.config.js
module.exports = {
  setupFilesAfterEnv: ['./jest.setup.js']
}


0

누군가 위의 문제 사용 방법을 수정하지 않으면 화살표 기능으로 비동기 기능을 둘러 싸서 내 문제를 해결했습니다. 에서처럼 :

describe("Profile Tab Exists and Clickable: /settings/user", () => {
    test(`Assert that you can click the profile tab`, (() => {
      async () => {
        await page.waitForSelector(PROFILE.TAB)
        await page.click(PROFILE.TAB)
      }
    })(), 30000);
});

1
화살표 기능을 비동기 주위에 놓아도 테스트가 완료 될 때까지 기다리지 않아도되므로 오류가 발생하지는 않지만 스레드 외부에서 테스트가 실행됩니다. 이 코드를 테스트하지 않고이 테스트가 완료되기 전에 전체 테스트 스위트가 완료 될 수 있습니다. b)이 테스트 내의 향후 오류가 스위트의 다른 테스트 중에 나타날 수 있으므로 테스트가 비정상적이고 유지하기가 어렵습니다.
Mary Shaw

0

제 경우에는이 오류가 무작위로 나타나기 시작하여 시간 제한을 30000으로 설정 한 후에도 사라지지 않습니다. 터미널에서 프로세스를 종료하고 테스트를 다시 실행하면 문제가 해결되었습니다. 또한 시간 초과를 제거했으며 테스트가 여전히 다시 통과합니다.


-2

노드에서 ... 예를 들어 사람들이 사용한 것을 아래에서 fakeEventEmitter

import { EventEmitter } from 'events';
describe('your case', () => {
 let fakeEventEmitter: EventEmitter;
 beforeEach(async () => {
   fakeEventEmitter = new EventEmitter();
   (fakeEventEmitter as any).pid = 123;
 }),
 it('should do something you want to do', done => {
            anAsynchronouseFunction(testOptions, context).subscribe({
                complete: () => {
                    expect(something).toBeTruthy();
                    done();
                }
            });
            fakeEventEmitter.emit('exit', 0);
        });
});
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.