Jest: El proceso de broma no se cierra después de que se completa la última prueba

Creado en 18 ago. 2016  ·  60Comentarios  ·  Fuente: facebook/jest

Tengo problemas con el proceso de Jest que no se completa después de que se completa la última prueba. El usuario deberá forzar la salida del proceso con ctrl-c. Mi teoría es que los autores de la prueba no están limpiando adecuadamente todos los recursos, pero lo ideal es que Jest se retire de todos modos.

Específicamente, estoy probando Firebase con firebase-server , activando uno o más servidores para cada prueba. En una acción afterEach llamamos al método close para todos los servidores creados en la última prueba, sin embargo, incluso con este método, el proceso Jest todavía no se cierra.

¿Hay alguna forma de forzar el cierre del proceso de Jest una vez que las pruebas hayan finalizado (aprobado o reprobado)? ¿Hay alguna manera de obtener un gancho afterAll para limpiar todos los recursos sobrantes? ¿Hay alguna manera de depurar qué evita exactamente que se cierre el proceso de Jest? Gracias.

Enhancement Help Wanted good first issue

Comentario más útil

para cualquiera que esté leyendo, puede usar la bandera --forceExit para acceder a esta funcionalidad. 🎉

Todos 60 comentarios

No tenemos una buena forma de hacerlo ahora. Recomendaría intentar conectar un depurador (Inspector de Chrome) para averiguar qué está pasando. Si sabe qué crea el trabajo asíncrono, potencialmente también puede parchearlo y rastrearlo (como poner algo alrededor de Promise.prototype.then)

¿Hay alguna razón por la que no se pueda forzar el cierre del trabajo asíncrono cuando todos los afterEach / after hayan resuelto?

No sé cómo mataría los procesos asincrónicos existentes si no los controla.

Migré de ava y esto no fue un problema, así que tal vez haya una respuesta. Tal vez eso sea process.exit en Node.js

Podríamos hacer eso, supongo, pero me preocupa que la gente no cuelgue cuando debería y no cierran sus recursos correctamente.

cc @dmitriiabramov ¿qué opinas?

Un ejemplo: de hecho, me encontré con esto con Jest, donde teníamos un proceso de observación de larga duración que no terminaría con Jest. Si Jest se hubiera suicidado durante la ejecución de la prueba (¡je!), Nunca me habría dado cuenta del problema y habría enviado una versión que se bloquearía cuando la gente intentara usarla.

No estoy seguro de si es seguro forzar la finalización del proceso. Al mismo tiempo, si las personas desean realizar un procesamiento posterior asíncrono después de que se hayan realizado las pruebas, pueden usar el gancho after all que esperará a que termine antes de salir del proceso.

el otro problema que podríamos tener es cortar el flujo de salida antes de que termine de imprimirse. Tuvimos este problema antes, cuando los mensajes de error no tienen tiempo suficiente para imprimirse antes de que finalice el proceso.

La pregunta es si podríamos encontrar una manera para que Jest diga "Parece que algunas pruebas no se están limpiando por sí mismas. Esto es lo que está sucediendo".

Un gancho after all podría ayudarme aquí, pero no he visto tal cosa en la documentación (solo afterEach ) ¿Me falta algo?

En cuanto a probar las limpiezas correctas, si pudiera probar si los _files_ se completaban a tiempo y si no usaban una función de bisección para aislar el problema (como en rspec).

De acuerdo, después de más investigación, esto parece ser un problema con Firebase en sí, y no hay forma de limpiar más que llamar a process.exit .

Recursos:

Todas las soluciones incluyen llamar manualmente process.exit . Tengo miedo de hacer esto en un contexto de broma, ¿hay alguna recomendación sobre dónde hacer esa llamada? Mi primer pensamiento fue algo como:

afterAll(() => setTimeout(() => process.exit(), 1000))

... para salir un segundo después de que todas las pruebas terminaron de ejecutarse para permitir que Jest haga lo suyo, sin embargo, no estoy seguro de cómo esto afecta el modo de reloj, y si estoy en lo cierto, Jest hace algunas cosas de paralelismo sofisticado que podrían hacer que esto no funcione como se esperaba. Alternativamente, ¿sería esto algo que necesita arreglar en Jest propiamente dicho? Si esto parece un arma de fuego para varias personas, ¿por qué no ponerlo en broma? O al menos un cambio entre el modo "advertir" y el modo "matar".

Me encantaría una bandera --exit o algo (podría ser un comentario por archivo o algo así) que cierre automáticamente los procesos cuando se completen las pruebas, similar a mocha. es un poco molesto cerrar manualmente todas las conexiones en cada archivo de prueba.

Tengo el mismo problema cuando ejecuto pruebas en Codeship . También falla en drone.io .
Aunque a nivel local funciona correctamente.

EDITAR:

  • Versión de broma : 15.1.1
  • Local :

    • Nodo: 6.2.2

    • npm: 3.9.5

  • Código de envío :

    • Nodo: 6.5.0

    • npm: 3.10.3

  • Drone.io

    • Nodo: 0.10.26

    • npm: 1.4.3

Me parece que Firebase debería arreglarse.

No tengo reservas en contra de agregar una opción llamada --forceExitAfterTestRun y debería ser fácil de agregar. Creo que solo requiere un cambio para salir aquí: https://github.com/facebook/jest/blob/master/packages/jest-cli/src/cli/index.js#L41 si la bandera se da independientemente de la resultado.

Parece ser una especie de condición de carrera. A veces se cierra después de ejecutar todas las pruebas localmente, a veces no ...

También estoy ejecutando esto después de comenzar a usar Jest para mis especificaciones de API donde estoy usando una base de datos real en lugar de simulacros (lo siento, pero las instantáneas son excelentes para esto). Todavía he podido resolver el problema incluso después de agregar afterAll ganchos para limpiar las conexiones, lo que me lleva a creer que está relacionado de alguna manera con mi población de accesorios en setupFiles , no el más fácil de depurar.

Jasmine parece tener la opción --forceexit , así que no me quejaría si algo similar también aterrizara en Jest 🙏

Otro problema: si una prueba falla, no se llama a afterAll() , por lo que no se limpia nada y no se cierra nada. Creo que --bail solucionará esto, pero aún no lo he probado

Si alguien quisiera enviar un PR, esto es algo con lo que podríamos ayudarnos y describí los detalles en mi comentario anterior :)

Lo intentaré si tengo algo de tiempo durante el fin de semana. Si alguien quiere hacerlo antes, estaría bien: sonríe:

Cierre a favor del PR que acaba de abrir. Continuaremos la discusión allí.

para cualquiera que esté leyendo, puede usar la bandera --forceExit para acceder a esta funcionalidad. 🎉

Para los usuarios de Google: Jest no sale en Jenkins CI, mientras que lo hace localmente .. --forceExit hecho lo arregló para mí.

Para mí fue olvidar manejar la promesa con .then (() => {}) - hizo el trabajo

Todavía estoy luchando con esto. Estoy probando una API con async y await . Me conecto a mi aplicación express y hago ping a un punto final, pero la prueba no se cierra. Intenté cerrar la conexión a mongodb y al servidor, pero aún está abierta. Solo estoy enviando un json vacío.

En mi caso, esto terminó siendo un problema de Firebase. Utilizando

afterAll(() => {
  firebaseApp.database().goOffline();
  firebaseApp.delete();
});

Parece funcionar. Descubrí que ambas líneas son realmente necesarias y que debes usar el mismo firebaseApp que originalmente obtienes de .initializeApp() .

¿Hay alguna forma de resolver esto sin forzar la salida?

Jest 23 incluye una bandera llamada --detectOpenHandles que debe señalar la fuente de por qué Jest no puede salir

--detectOpenHandles devuelve mongoose.connect y mongoose.model. Intentar mongoose.disconnect en afterAll genera un error de mongo Topología destruida.

screenshot 2018-06-08 11 14 51
screenshot 2018-06-08 11 14 29

@elkhan, ¿ has averiguado cómo resolver los problemas de las mangostas?

Después de agregar --detectOpenHandles , Jest no solo completa mis pruebas y tampoco muestra nada que realmente bloquee a Jest, lo cual es extraño. Parece un error.

Para mí, --forceExit resuelve el problema, al mismo tiempo uso --detectOpenHandles pero no detecta nada (tanto localmente como en CircleCI). También estoy corriendo con --runInBand .

Para mí, eliminar --runInBand resolvió.

--forceExit resuelve el problema también cuando utilizo envío ... Intenté --detectOpenHandles pero no obtuve ningún resultado y aún así causé que la compilación se bloqueara

Agregar --detectOpenHandles soluciona el problema, que es extraño.

Nodo: v8.12.0
Broma: v23.6.0

Agregar --detectOpenHandles o --forceExit no soluciona el problema cuando se ejecuta en Codeship.

jest --ci --verbose --forceExit --detectOpenHandle

Nodo: v8.12.0
Broma: v23.6.0

@sibelius una forma de evitar este problema es silenciando la función init del modelo

const mongoose = require('mongoose');

mongoose.Model.init = () => {};

Esto evitará que Jest se queje de los modelos, aunque no se crearán índices.

db.collection("test-collection").add({
    title: 'post title',
    content: 'This is the test post content.',
    date: new Date(),
})
    .then(docRef => {
        console.log('Document written with ID: ', docRef);
    })
    .catch(error => {
        console.error('Error adding document: ', error);
    });

jest --forceExit --detectOpenHandle las pruebas se pasan, pero el código en .then o .catch no se ejecuta !!
¿algunas ideas?

@alexpchin Así es como lo resolví:

    beforeAll(async (done) => {
        dbConnection = await mongoose.connect(...)
        done()
    })

    afterAll(async (done) => {
        await dbConnection.close()
        dbConnection.on('disconnected', done)
    })

Con NestJs tuve que agregar

afterAll(() => {
  app.close();
});

Descubrimos que este problema fue causado por el proceso de broma que se quedó sin memoria. Agregar --maxWorkers=10 solucionó el problema.

Estoy agregando esta causa, tal vez alguien que se pregunte sobre este problema podría tener la razón de esto como yo.
Estaba usando Jest dentro de Travis para probar una aplicación NodeJS y Travis siguió colgando hasta el tiempo de espera directamente después de Jest. Parece que Jest no estaba cerrando.
Después de muchos intentos, descubrí que la razón era usar jest con JSDom.
Tenía la siguiente línea en mi archivo jest.config.js :

  'testURL': 'http://localhost/',

Lo que provocó que JSDom se cargara y supuestamente no cerrara todos los recursos con gracia y mantuviera vivo a Jest.

Lo resolví eliminando la línea; sin embargo, Jest fallará con el siguiente error, vea esto :

SecurityError: localStorage is not available for opaque origins

Para resolverlo agregué lo siguiente a jest.config.js :

  'testEnvironment': 'node',

Espero que eso ayude a alguien. Estoy agregando esta causa, tal vez alguien que se esté preguntando sobre este problema podría tener la razón de esto como yo.
Estaba usando Jest dentro de Travis para probar una aplicación NodeJS y Travis siguió colgando hasta el tiempo de espera directamente después de Jest. Parece que Jest no estaba cerrando.
Después de muchos intentos, descubrí que la razón era usar jest con JSDom.
Tenía la siguiente línea en mi archivo jest.config.js :

  'testURL': 'http://localhost/',

Lo que hizo que JSDom se cargara y supuestamente no cerrara todos los recursos con gracia y mantuviera vivo a Jest.

Lo resolví eliminando la línea; sin embargo, Jest fallará con el siguiente error, vea esto :

SecurityError: localStorage is not available for opaque origins

Para resolverlo, agregué lo siguiente a jest.config.js :

  'testEnvironment': 'node',

Espero que ayude a alguien.

--forceSalir --detectOpenHandles --maxWorkers = 10

lo hizo por nosotros

nodo: 8.11.3
broma 23.6.0

Con NestJs tuve que agregar

afterAll(() => {
  app.close();
});

Dejando esto aquí para la gente de NestJS:
Con NestJS, descubrí que la respuesta anterior funciona.
Lo que NO funciona es lo siguiente:

afterAll(async () => {
        await app.close()
    })

para mí, es --forceExit --maxWorkers=10 que funciona (estoy en Ubuntu 18.04, usando [email protected])

En mi caso, el uso de NodeJS 10 u 11 soluciona el problema, pero todavía está allí con el Nodo 6 o el Nodo 8. No se muestra nada cuando se usa la opción --detectOpenHandles , y --forceExit soluciona el problema.

+1 persona más aquí (como @motss y @seanlindo ) observando que el _ "La broma no salió un segundo después de que se haya completado la ejecución de la prueba". _ Ocurre solo cuando --detectOpenHandles no se usa.

[email protected]

Las pruebas fallan constantemente sin --detectOpenHandles pero pasan y no muestran identificadores abiertos cuando se ejecutan con --detectOpenHandles .

La máquina / contenedor que ejecuta las pruebas tiene dos núcleos, pero de forma predeterminada, las pruebas se ejecutan con maxWorkers=1

Cuando agrego la bandera --detectOpenHandles y miro config / globalConfig usando la bandera --debug , el detectOpenHandles es la diferencia _only_ ...

Si ejecuto with --runInBand --detectOpenHandles pruebas aún pasan bien.

Puedo ejecutar usando cualquiera de los siguientes para finalizar las pruebas con éxito sin mostrar el error "... no salió ...":

  • jest --maxWorkers=2
  • jest --detectOpenHandles
  • jest --forceExit

Trabajando con maxWorkers=2 por ahora, pero esas son mis observaciones, solo para cualquiera que busque en el futuro ...

_Editar: Detalle adicional: esto solo afecta a mi entorno CI, que es un contenedor docker DE alpine: 3.7 en ejecución del nodo v8.9.3. No puedo reproducir con --maxWorkers=1 en mi máquina de desarrollo_

Confirmando que recibo este error ahora mismo. El uso de --maxWorkers=10 parece solucionar el problema.

Entonces ... Estuve luchando con esto durante bastante tiempo (usando travis ci, overoles y mecanografiado).
Terminaría colgando y produciendo una compilación fallida (pero solo con Travis CI).

Después de mucho ensayo y error, encontré que lo que solucionó esto para mí fue que agregué una ruta explícita a las pruebas.

Falló con el script npm

   "test": "jest",
    "test:coverage": "npm run test -- --collectCoverage && cat ./src/coverage/lcov.info | coveralls",

Y pasó (en travis ci) con:

   "test": "jest .*\.test\.ts",
    "test:coverage": "npm run test -- --collectCoverage && cat ./src/coverage/lcov.info | coveralls",

Si está utilizando la ventana acoplable con una imagen de Redhat UBI y create-react-app asegúrese de configurar CI=true antes de ejecutar npm test

Diciembre de 2019. Me encontré con este problema SOLO en Travis. Las pruebas pasan localmente. La solución de @qopqopqop funcionó para mí. Usando Jest versión 24.9.0

Solo encontré este error cuando nuestro proyecto comenzó a agregar nuevos componentes que usan hooks y testing-library. Creo que puede haber cierta fricción entre Jest, testing-library y React hooks, ya que todas son tecnologías nuevas. Estos proyectos todavía están aprendiendo a jugar bien entre ellos. O, podríamos estar escribiendo componentes funcionales realmente defectuosos que usan ganchos de manera incorrecta. :-)

Todavía tengo este problema. No puedo salir de la prueba, esto hace que npm test falle para toda mi aplicación. ¿Cualquier pista?

@koooge ¿Puedes publicar un ejemplo de lo que no funciona para ti?

Para hacer que la prueba salga con 0 después de que todas las pruebas pasen, debe pasar --watchAll = false
como npm ejecutar prueba - --watchAll = false

esto funcionó para mí

Para que esto funcione con Firebase, tuve que hacer esto:

afterAll(() => {
    firebase.app().delete();
});

Lo arreglé usando la opción:

--forceSalir

https://jestjs.io/docs/en/cli# --forceexit

Así que también me encontré con este problema. Fue molesto ver el mensaje de advertencia A worker process has failed to exit gracefully and has been force exited... cuando supe que estaba manejando todas mis llamadas async correctamente. Ejecuté mis pruebas con --detectOpenHandles pero no apareció nada. Después de investigar un poco, descubrí que mi culpable era Promise.race .

Utilizo una biblioteca de utilidades de promesas nativas (https://github.com/blend/promise-utils) y envuelvo algunas de mis llamadas de API externas en la utilidad timeout . Esta utilidad, a su vez, utiliza el Promise.race nativo.

Saqué ese código y creé un caso de prueba simple para confirmar mis hallazgos.

it('promise.race', async() => {
  await Promise.race([
    new Promise((res) => setTimeout(res, 10000)),
    Promise.resolve('true')
  ])
})

Suponiendo que la configuración de tiempo de espera de su caso de prueba sea predeterminada, la prueba anterior siempre dará la advertencia.

Independientemente de la forma en que jest esté usando para detectar manijas abiertas debajo del capó, no está tomando en consideración las manijas que Promise.race dejaron abiertas intencionalmente. Este caso de uso definitivamente cae dentro de la categoría de falso positivo. No estoy seguro de que este falso positivo se pueda arreglar, pero quizás uno de los desarrolladores tenga una solución ingeniosa para esto.

Por ahora, me quedo con --forceExit como todos los demás.

Editar:
Acabo de encontrar esto, parece que de hecho es un problema más profundo de nodejs / v8 https://github.com/nodejs/node/issues/24321

Para cualquier otra persona que venga aquí de las pruebas de Firestore, esto funciona para mí:

afterAll(async () => {
  // Shut down Firestore, otherwise jest doesn't exit cleanly
  await firestoreInstance.terminate()
});

Sigo teniendo el mismo problema con Apollo & Jest. Desafortunadamente, aunque la opción --detectOpenHandles eventualmente sale, todavía hace que el proceso quede pendiente por unos segundos más (y en contradicción con su nombre: ¡no proporciona información sobre qué identificadores están todavía abiertos!).

Usar --forceExit hace el trabajo pero imprime de manera molesta:

Forzar la salida de Jest: ¿Ha considerado usar --detectOpenHandles para detectar operaciones asíncronas que siguieron ejecutándose después de> finalizar todas las pruebas?

Una solución alternativa que encontré (¡y de ninguna manera es una solución!) Es agregar teardown a jest.config.js:

globalTeardown: '<rootDir>/__tests__/teardown.js',

y en teardown.js use process.exit:

module.exports = async function () {
    console.log('done!');
    process.exit(0);
}

También tengo este problema. ¿Cómo puedo arreglarlo? He configurado forceExit: true . --forceExit --detectOpenHandles --maxWorkers=10 no funciona.

https://github.com/atom-ide-community/atom-ide-base/pull/33

Editar: el problema en otro lugar. Está en el corredor de pruebas que estoy usando ...

@alusicode
Este no me funcionó npm test --watchAll=false
Pero funcionó agregando --watchAll=false en el archivo package.json. 👍

Me gusta

"test": "react-scripts test a jest --ci --reporters=default --reporters=jest-junit --watchAll=false"

Documentos oficiales: https://jestjs.io/docs/en/cli.html# --watchall

No uso firebase pero tuve el mismo problema en mis scripts de flujo de trabajo. el uso de jest sin parámetros decía que algunos de mis scripts no se cerraban correctamente y que debería usar --runInBand --detectOpenHandles . Eso solucionaría el problema de todas mis pruebas excepto una (por cierto, --detectOpenHandles me mostró las pruebas que tenían problemas).
Entonces comencé a revisar todas las pruebas una por una. Descubrí que durante 2 pruebas olvidé usar await cuando estaba llamando a una función asíncrona.
Después de agregar espera, se corrigió. Aunque no creo que sea normal que --detectOpenHandles no imprima los problemas.

¿Fue útil esta página
0 / 5 - 0 calificaciones