La devolución de llamada asincrónica no se invocó dentro del tiempo de espera de 5000 ms especificado por jest.setTimeout


238

Estoy usando titiritero y broma para ejecutar algunas pruebas de front-end.

Mis pruebas se ven de la siguiente manera:

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

A veces, cuando ejecuto las pruebas, todo funciona como se esperaba. Otras veces, recibo un error:

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)

Esto es extraño porque:

  1. Especifiqué que el tiempo de espera sea 30000

  2. Si recibo o no este error es aparentemente muy aleatorio

¿Alguien puede adivinar por qué está sucediendo esto?


¿Qué línea está agotando el tiempo de espera?
lloyd

@Asool ¿Podría proporcionar un repositorio de GitHub? Para nosotros será más fácil y rápido brindarle una solución. :)
Shishir Anshuman

@Asool, cualquier comentario sobre la respuesta que
publiqué

1
¿podría ser que la prueba realmente falla para los 30000 ms pero el error de broma simplemente no incluye el valor que pasó? es decir, si pone un tiempo de espera de 0 ms, ¿cambia el error de broma?
Nirit Levi el

Vi este error cuando estaba depurando mis pruebas. Al detenerse en un punto de interrupción se produjo este error
Neets

Respuestas:


261

Por lo tanto, el tiempo de espera que especifique aquí debe ser más corto que el tiempo de espera predeterminado.

El tiempo de espera predeterminado es 5000y el marco por defecto es jasmineen caso de jest. Puede especificar el tiempo de espera dentro de la prueba agregando

jest.setTimeout(30000);

Pero esto sería específico para la prueba. O puede configurar el archivo de configuración para el marco.

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)

Ver este hilo también

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

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

La falta de ortografía de PS setupFilesAfterEnv(es decir setupFileAfterEnv) también arrojará el mismo error.


2
Gracias por responder una pregunta que no pude encontrar fácilmente a través de la documentación de Jest.
HartleySan

21
Como esto me ayudó, podría valer la pena señalar que la setupTestFrameworkScriptFileha sustituido por setupFilesAfterEnv, por lo que se conviertesetupFilesAfterEnv: ["./jest.setup.js"]
Maxim Geerinck

1
También descubrí que jest.setTimeout(10000)podría agregarse a una sola prueba para un caso perimetral, por lo que no fue necesario cambiar toda la configuración :)
James

Debería perder algo, pero si añado jest.setTimeout(30000);en el jest.config.jsrecibo "ReferenceError: broma no está definido". Intenté agregar const jest = require("jest");pero luego aparece "TypeError: jest.setTimeout no es una función".
Jean Paul

Vaya, leí demasiado rápido: el setupFilesAfterEnvargumento en jest.config.jsapuntará a otro archivo donde ponemos la jest.setTimeout(30000)opción. Es bueno que podamos configurar esto, pero me parece un poco complicado.
Jean Paul

64

Debería llamar al async/awaitcuando es asíncrono de la prueba.

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
¿Por qué deberíamos tener doneuna función asíncrona? ¿No simplemente devolvemos Promise o undefined?
Charlie Schliesser

2
No, esto no es correcto. No necesita llamar a done () ya que está esperando sus promesas o simplemente podría regresar page.click. done () se usa, al menos en mi caso, principalmente para probar con devoluciones de llamada.
Justin

2
Gracias chicos, he eliminado la donedevolución de llamada que no es necesaria.
código de schrodinger

26
¿No es este el mismo código que en la pregunta original ahora?
Joe

1
La presencia de un parámetro (nombrado doneen este caso) en la devolución de llamada hace que Jest espere hasta que se llame a este parámetro. Su presencia es significativa incluso si no se usa.
Vaughan

54

La respuesta a esta pregunta ha cambiado a medida que Jest ha evolucionado. Respuesta actual (marzo de 2019):

  1. Puede anular el tiempo de espera de cualquier prueba individual agregando un tercer parámetro al it. es decir.it('runs slow', () => {...}, 9999)

  2. Puede cambiar el valor predeterminado usando jest.setTimeout. Para hacer esto:

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

y

// File: src/jest/defaultTimeout.js
/* global jest */
jest.setTimeout(1000)
  1. Como otros han señalado, y no están directamente relacionados con esto, doneno es necesario con el enfoque asíncrono / espera.

55
esta es la versión más moderna
jonashdown

23

Me gustaría agregar (esto es un poco largo para un comentario) que incluso con un tiempo de espera de 3000mis pruebas todavía a veces (al azar) fallaba con

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

Gracias a la gran respuesta de @ Tarun, creo que la forma más corta de arreglar muchas pruebas es:

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

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

99
No necesita llamar al jest.setTimeout()interior beforeEach, llamarlo una vez es suficiente para todas las pruebas.
Marcos Pereira

19

Esta es una actualización relativamente nueva, pero es mucho más sencilla. Si está utilizando jest 24.9.0 o superior, simplemente puede agregar testTimeouta su configuración:

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

17

Asegúrese de invocar done();en devoluciones de llamada o no pasará simplemente la prueba.

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

Se aplica a todas las demás funciones que tienen una devolución de llamada done ().


1
Bien mencionado, @ZenVentzi. Gracias :)!
ivanleoncz

11

Para jest 24.9+, también puede establecer el tiempo de espera desde la línea de comando agregando --testTimeout

Aquí hay un extracto de sus documentos

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

3

Recientemente me encontré con este problema por una razón diferente: estaba ejecutando algunas pruebas sincrónicamente jest -i, y solo se agotaba el tiempo de espera. Para cualquier razonamiento, ejecutar las mismas pruebas usando jest --runInBand(aunque -iesté destinado a ser un alias) no se agota el tiempo de espera.

Quizás esto ayude a alguien ¯\_(:/)_/¯


1

El problema de tiempo de espera se produce cuando la red es lenta o se realizan muchas llamadas de red await, estos escenarios exceden el tiempo de espera predeterminado, es decir, 5000 ms. Para evitar el error de tiempo de espera, simplemente aumente el tiempo de espera de los globales que admiten un tiempo de espera. Puede encontrar una lista de globales y su firma aquí .
Para Jest 24.9


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

Si en Jest <= 23:

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

Si en Jest> 23:

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


0

En caso de que alguien no solucione el problema, utilice los métodos anteriores, arreglé el mío rodeando la función asíncrona con una función de flecha. Como en:

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
Me parece que colocar la función de flecha alrededor del asíncrono no le indicará a la prueba que espere a que se complete, por lo que si bien es posible que no obtenga un error ahora, tendrá una prueba ejecutándose fuera de su hilo y a) todo el conjunto de pruebas puede completarse antes de que se realice esta prueba, no probar este código yb) los errores futuros dentro de esta prueba pueden aparecer durante una prueba diferente en la suite, haciendo que sus pruebas sean escamosas y difíciles de mantener.
Mary Shaw

0

En mi caso, este error comenzó a aparecer aleatoriamente y no desaparecería incluso después de establecer un tiempo de espera de 30000. Simplemente finalizar el proceso en el terminal y volver a ejecutar las pruebas resolvió el problema por mí. También eliminé el tiempo de espera y las pruebas aún pasan de nuevo.


-2

En Nodo ... lo que veo que la gente hizo como ejemplo está a continuación, usando 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);
        });
});
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.