Jest: Der Scherzprozess wird nach Abschluss des letzten Tests nicht beendet

Erstellt am 18. Aug. 2016  ·  60Kommentare  ·  Quelle: facebook/jest

Ich habe Probleme mit dem Jest-Prozess, der nach Abschluss des letzten Tests nicht abgeschlossen wird. Der Benutzer muss das Beenden des Prozesses mit Strg-C erzwingen. Meine Theorie ist, dass nicht alle Ressourcen von den Testautoren angemessen bereinigt werden, aber im Idealfall sollte Jest trotzdem aufhören.

Insbesondere teste ich Firebase mit firebase-server und starte für jeden Test einen oder mehrere Server. In einer afterEach -Aktion rufen wir die close -Methode für alle im letzten Test erstellten Server auf, aber selbst mit dieser Methode wird der Jest-Prozess immer noch nicht beendet.

Gibt es eine Möglichkeit, den Jest-Prozess nach Abschluss der Tests zum Beenden zu zwingen (bestanden oder nicht bestanden)? Gibt es eine Möglichkeit, einen afterAll -Hook zu erhalten, um alle verbleibenden Ressourcen zu bereinigen? Gibt es eine Möglichkeit zu debuggen, was genau verhindert, dass der Jest-Prozess beendet wird? Vielen Dank.

Enhancement Help Wanted good first issue

Hilfreichster Kommentar

Für jeden, der liest, können Sie das Flag --forceExit verwenden, um auf diese Funktionalität zuzugreifen. 🎉

Alle 60 Kommentare

Wir haben momentan keinen guten Weg, das zu tun. Ich würde empfehlen, einen Debugger (Chrome Inspector) anzuschließen, um herauszufinden, was los ist. Wenn Sie wissen, was die asynchrone Arbeit erzeugt, können Sie sie möglicherweise auch von Affen patchen und verfolgen (z. B. etwas um Promise.prototype.then setzen).

Gibt es einen Grund, warum asynchrone Arbeit nicht zwangsweise beendet werden kann, wenn alle afterEach / after Hooks aufgelöst wurden?

Ich weiß nicht, wie Sie vorhandene asynchrone Prozesse beenden würden, wenn Sie sie nicht im Griff hätten.

Ich bin von ava migriert und dies war kein Problem. Vielleicht gibt es eine Antwort? Vielleicht ist das process.exit in Node.js.

Wir könnten das tun, denke ich, aber ich mache mir Sorgen, dass die Leute nicht hängen bleiben, wenn es sollte, und dass sie ihre Ressourcen nicht richtig herunterfahren.

cc @dmitriiabramov was denkst du?

Ein Beispiel: Ich bin tatsächlich mit Jest selbst darauf gestoßen, wo wir einen lang laufenden Watcher-Prozess hatten, der Jest selbst nicht beenden würde. Wenn Jest sich während des Testlaufs umgebracht hätte (heh!), Hätte ich das Problem nie bemerkt und eine Version ausgeliefert, die hängen würde, wenn Leute versuchen, sie zu verwenden.

Ich bin mir nicht sicher, ob es sicher ist, den Prozess mit Gewalt zu beenden. Wenn Benutzer nach Abschluss der Tests eine asynchrone Nachbearbeitung durchführen möchten, können sie gleichzeitig den Hook after all , der auf den Abschluss wartet, bevor er den Prozess beendet.

Das andere Problem, das wir möglicherweise haben, ist das Schneiden des Ausgabestreams, bevor der Druckvorgang abgeschlossen ist. Wir hatten dieses Problem bereits, als Fehlermeldungen nicht genügend Zeit zum Drucken haben, bevor der Prozess beendet wird.

Die Frage ist, ob wir einen Weg finden könnten, wie Jest sagen kann: "Es sieht so aus, als würden einige Tests nicht nach sich selbst aufräumen. Hier ist, was los ist."

Ein after all -Haken könnte mir hier helfen, aber ich habe so etwas in der Dokumentation nicht gesehen (nur afterEach ) Vermisse ich etwas?

Was das Testen korrekter Bereinigungen betrifft, wenn Sie testen könnten, ob _files_ rechtzeitig abgeschlossen wurde und ob sie keine Halbierungsfunktion verwenden, um das Problem zu isolieren (wie in rspec).

Ok, nach weiteren Recherchen scheint dies ein Problem mit Firebase selbst zu sein, und es gibt keine Möglichkeit, ohne das Aufrufen von process.exit zu bereinigen.

Ressourcen:

Bei allen Problemumgehungen wird process.exit manuell aufgerufen. Ich habe Angst, dies in einem Scherzkontext zu tun. Gibt es eine Empfehlung, wo ein solcher Anruf getätigt werden soll? Mein erster Gedanke war so etwas wie:

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

… Um eine Sekunde nach Beendigung aller Tests zu beenden, damit Jest seine Sache machen kann, bin ich mir jedoch nicht sicher, wie sich dies auf den Überwachungsmodus auswirkt, und wenn ich richtig bin, macht Jest einige ausgefallene Parallelitätsaufgaben, die dazu führen könnten, dass dies nicht wie erwartet funktioniert. Alternativ wäre dies etwas, das Sie in Jest selbst beheben müssen? Wenn dies für eine Reihe von Menschen wie eine Fußwaffe erscheint, warum nicht in Jest? Oder zumindest ein Wechsel zwischen "Warn" -Modus und "Kill" -Modus.

Ich würde ein --exit Flag oder so etwas lieben (es könnte ein Kommentar pro Datei sein oder so), das die Prozesse automatisch schließt, wenn die Tests abgeschlossen sind, ähnlich wie bei Mokka. Es ist etwas ärgerlich, jede Verbindung in jeder Testdatei manuell zu schließen.

Ich habe das gleiche Problem, wenn ich Tests in Codeship durchführe . Es schlägt auch auf drone.io fehl .
Vor Ort funktioniert es allerdings einwandfrei.

BEARBEITEN:

  • Jest Version: 15.1.1
  • Lokal :

    • Knoten: 6.2.2

    • npm: 3.9.5

  • CodeShip :

    • Knoten: 6.5.0

    • npm: 3.10.3

  • Drone.io

    • Knoten: 0,10,26

    • npm: 1.4.3

Es scheint mir, dass Firebase repariert werden sollte.

Ich habe keine Bedenken gegen das Hinzufügen einer Option namens --forceExitAfterTestRun und es sollte einfach hinzuzufügen sein. Ich denke, es erfordert nur eine Änderung, um hier zu beenden :

Scheint eine Art Rennbedingung zu sein. Manchmal wird es beendet, nachdem alle Tests lokal ausgeführt wurden, manchmal nicht ...

Ich führe dies auch aus, nachdem ich angefangen habe, Jest für meine API-Spezifikationen zu verwenden, bei denen ich anstelle von Mocks eine echte Datenbank verwende (sorry, aber Snapshots sind dafür großartig). Ich noch in der Lage gewesen , das Problem zu lösen , selbst nach der Zugabe von afterAll Haken aufzuräumen Verbindungen was dazu führt mich ist es etwas zu glauben , wie man meine Bevölkerung von Vorrichtungen in Zusammenhang mit setupFiles , nicht die am einfachsten zu debuggen.

Jasmine scheint die Option --forceexit also würde ich mich nicht beschweren, wenn ähnlich auch Jest land landen würde

Ein weiteres Problem: Wenn ein Test fehlschlägt, wird afterAll() nicht aufgerufen, sodass nichts bereinigt und nichts geschlossen wird. Ich denke, --bail wird das beheben, aber ich habe das noch nicht versucht

Wenn jemand eine PR senden möchte, ist dies etwas, bei dem wir Hilfe gebrauchen könnten, und ich habe Details in meinem vorherigen Kommentar skizziert :)

Ich werde es versuchen, wenn ich über das Wochenende etwas Zeit habe. Wenn jemand es vorher machen will, wäre es cool: lächeln:

Abschluss zugunsten der gerade eröffneten PR. Wir werden die Diskussion dort fortsetzen.

Für jeden, der liest, können Sie das Flag --forceExit verwenden, um auf diese Funktionalität zuzugreifen. 🎉

Für Googler: Jest wird auf Jenkins CI nicht beendet, während es lokal ausgeführt wird. --forceExit tatsächlich für mich behoben.

Für mich war es, das Versprechen mit .then (() => {}) zu vergessen - hat den Job gemacht

Ich kämpfe immer noch damit. Ich teste eine API mit async und await . Ich verbinde mich mit meiner Express-Anwendung und pinge einen Endpunkt an, aber der Test wird nicht geschlossen. Ich habe versucht, die Verbindung zu Mongodb und zum Server zu schließen, aber sie ist noch offen. Ich schicke nur leeren Json zurück.

In meinem Fall war dies ein Firebase-Problem. Verwenden von

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

scheint den Trick zu tun. Ich habe festgestellt, dass beide Zeilen tatsächlich notwendig sind und dass Sie dasselbe firebaseApp , das Sie ursprünglich von .initializeApp() .

Gibt es eine Möglichkeit, dies ohne forceExit zu lösen?

Jest 23 enthält ein Flag namens --detectOpenHandles das auf die Quelle hinweisen sollte, warum Jest nicht beendet werden kann

--detectOpenHandles gibt mongoose.connect und mongoose.model zurück. Der Versuch, mongoose.disconnect in afterAll auszuführen, löst einen Mongo-Fehler aus. Topologie zerstört.

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

@elkhan hast du herausgefunden, wie man

Nach dem Hinzufügen von --detectOpenHandles schließt Jest nicht nur meine Tests ab und zeigt auch nichts an, was Jest tatsächlich blockiert, was seltsam ist. Sieht aus wie ein Käfer.

Für mich löst --forceExit das Problem, gleichzeitig verwende ich --detectOpenHandles aber es erkennt nichts (sowohl lokal als auch auf CircleCI). Ich laufe auch mit --runInBand .

Für mich hat das Entfernen von --runInBand Problem gelöst.

--forceExit löst das Problem auch für mich, wenn ich Shippable verwende ... Versuchte --detectOpenHandles , gab aber keine Ergebnisse und ließ den Build trotzdem hängen

Das Hinzufügen von --detectOpenHandles behebt das bizarre Problem.

Knoten: v8.12.0
Scherz: v23.6.0

Das Hinzufügen von --detectOpenHandles oder --forceExit behebt das Problem bei der Ausführung mit Codeship nicht.

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

Knoten: v8.12.0
Scherz: v23.6.0

@sibelius Eine Möglichkeit, dieses Problem zu vermeiden, besteht darin, die Init-Funktion des Modells

const mongoose = require('mongoose');

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

Dies verhindert, dass sich Jest über die Modelle beschwert, obwohl keine Indizes erstellt werden

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 die Tests sind bestanden, aber der Code in .then oder .catch wird nicht ausgeführt !!
irgendwelche Ideen?

@alexpchin So habe ich es gelöst:

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

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

Mit NestJs musste ich hinzufügen

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

Wir haben festgestellt, dass dieses Problem durch den Scherzprozess verursacht wurde, dem der Speicher ausgeht. Das Hinzufügen von --maxWorkers=10 das Problem für uns behoben.

Ich füge diese Ursache hinzu, vielleicht hat jemand, der sich über dieses Problem wundert, den Grund dafür wie ich.
Ich habe Jest in Travis verwendet, um eine NodeJS-App zu testen, und Travis blieb bis zum Timeout direkt nach Jest hängen. Anscheinend wurde Jest nicht geschlossen.
Nach vielen Versuchen stellte ich fest, dass der Grund darin bestand, Scherz mit JSDom zu verwenden.
Ich hatte die folgende Zeile in meiner jest.config.js -Datei:

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

Dies führte dazu, dass JSDom geladen wurde und angeblich nicht alle Ressourcen ordnungsgemäß geschlossen wurde und Jest am Leben blieb.

Ich löste es durch die Linie zu entfernen - aber Jest wird dann nicht mit dem folgenden Fehler dies sehen :

SecurityError: localStorage is not available for opaque origins

Um es zu lösen, habe ich jest.config.js Folgendes hinzugefügt:

  'testEnvironment': 'node',

Hoffe, das hilft jedem. Ich füge diese Ursache hinzu, vielleicht hat jemand, der sich über dieses Problem wundert, den Grund dafür, wie ich es getan habe.
Ich habe Jest in Travis verwendet, um eine NodeJS-App zu testen, und Travis blieb bis zum Timeout direkt nach Jest hängen. Anscheinend wurde Jest nicht geschlossen.
Nach vielen Versuchen stellte ich fest, dass der Grund darin bestand, Scherz mit JSDom zu verwenden.
Ich hatte die folgende Zeile in meiner jest.config.js -Datei:

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

Dies führte dazu, dass JSDom geladen wurde und angeblich nicht alle Ressourcen ordnungsgemäß geschlossen wurde und Jest am Leben blieb.

Ich löste es durch die Linie zu entfernen - aber Jest wird dann nicht mit dem folgenden Fehler dies sehen :

SecurityError: localStorage is not available for opaque origins

Um es zu lösen, habe ich jest.config.js Folgendes hinzugefügt:

  'testEnvironment': 'node',

Hoffe das hilft jedem.

--forceExit --detectOpenHandles --maxWorkers = 10

hat es für uns getan

Knoten: 8.11.3
Scherz 23.6.0

Mit NestJs musste ich hinzufügen

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

Lassen Sie dies hier für NestJS-Leute:
Bei NestJS habe ich festgestellt, dass die obige Antwort funktioniert.
Was nicht funktioniert, ist Folgendes:

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

Für mich funktioniert --forceExit --maxWorkers=10 (ich bin unter Ubuntu 18.04 und benutze [email protected]).

In meinem Fall wird das Problem mit NodeJS 10 oder 11 behoben, aber mit Node 6 oder Node 8 ist es immer noch vorhanden. Bei Verwendung der Option --detectOpenHandles nichts angezeigt, und mit --forceExit das Problem ebenfalls behoben.

+1 weitere Person hier (wie @motss und @seanlindo ) beobachtet, dass der _ "Jest nicht eine Sekunde nach Abschluss des Testlaufs beendet wurde." _ Tritt nur auf, wenn --detectOpenHandles nicht verwendet wird.

[email protected]

Tests schlagen ohne --detectOpenHandles konsistent fehl, bestehen jedoch und zeigen keine offenen Handles, wenn sie mit --detectOpenHandles .

Der Computer / Container, auf dem die Tests ausgeführt werden, verfügt über zwei Kerne. Standardmäßig werden Tests jedoch mit maxWorkers=1

Wenn ich das --detectOpenHandles -Flag hinzufüge und die config / globalConfig mit dem --debug -Flag betrachte, ist der detectOpenHandles -Wert der _nur_ Unterschied ...

Wenn ich with --runInBand --detectOpenHandles ausführe, bestehen die Tests immer noch gut.

Ich kann eine der folgenden Aktionen ausführen, um die Tests erfolgreich abzuschließen, ohne den Fehler "... wurde nicht beendet ..." anzuzeigen:

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

Ich arbeite jetzt mit maxWorkers=2 , aber das sind meine Beobachtungen, nur für alle, die in Zukunft suchen ...

_Edit: Zusätzliches Detail: Dies betrifft nur meine CI-Umgebung, bei der es sich um einen Docker-Container handelt. FROM alpine: 3.7 Ausführen von Node v8.9.3. Ich kann nicht mit --maxWorkers=1 auf meiner Entwicklungsmaschine reproduzieren

Bestätigung, dass ich diesen Fehler jetzt erhalte. Die Verwendung von --maxWorkers=10 scheint das Problem zu beheben.

Also ... ich habe eine ganze Weile damit gekämpft (mit Travis CI, Overalls und Typoskript).
Es würde hängen bleiben und einen fehlgeschlagenen Build produzieren (aber nur mit Travis CI).

Nach langem Ausprobieren stellte ich fest, dass dies für mich behoben wurde, indem ich einen expliziten Pfad zu den Tests hinzufügte.

Es ist mit dem npm-Skript fehlgeschlagen

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

Und bestanden (in travis ci) mit:

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

Wenn Sie Docker mit einem Redhat-UBI-Image und create-react-app stellen Sie sicher, dass Sie CI=true festlegen, bevor Sie npm test

Dezember 2019. Ist auf diese Ausgabe NUR bei Travis gestoßen. Tests bestehen lokal. @qopqopqop 's Fix hat bei mir funktioniert. Verwenden von Jest Version 24.9.0

Dieser Fehler trat erst auf, als unser Projekt neue Komponenten hinzufügte, die Hooks und Testbibliothek verwenden. Ich denke, es kann einige Reibungen zwischen Jest, Testbibliothek und React-Hooks geben, da dies alles neue Technologien sind. Diese Projekte lernen immer noch, wie man gut miteinander spielt. ODER wir könnten wirklich fehlerhafte Funktionskomponenten schreiben, die Hooks falsch verwenden. :-)

Ich habe immer noch dieses Problem. Ich kann den Test nicht beenden. Dadurch schlägt npm test für alle meine Apps fehl. irgendeine Ahnung?

@koooge Kannst du ein Beispiel dafür posten, was bei dir nicht funktioniert?

Um den Test nach bestandenem Test mit 0 zu beenden, müssen Sie --watchAll = false übergeben
wie npm run test - --watchAll = false

das hat bei mir funktioniert

Damit dies mit Firebase funktioniert, musste ich Folgendes tun:

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

Ich habe es mit der Option behoben:

--forceExit

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

Also bin ich auch auf dieses Problem gestoßen. Es war ärgerlich, die Warnmeldung A worker process has failed to exit gracefully and has been force exited... , als ich wusste, dass ich alle meine async -Anrufe korrekt abwickelte. Ich habe meine Tests mit --detectOpenHandles aber es wurde nichts angezeigt. Nach einigen Recherchen stellte ich fest, dass mein Schuldiger Promise.race .

Ich verwende eine native Versprechensdienstprogrammbibliothek (https://github.com/blend/promise-utils) und verpacke einige meiner externen API-Aufrufe in das Dienstprogramm timeout . Dieses Dienstprogramm verwendet wiederum das native Promise.race .

Ich zog diesen Code heraus und erstellte einen einfachen Testfall, um meine Ergebnisse zu bestätigen.

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

Angenommen, Ihre Timeout-Einstellungen für Testfälle sind Standard, gibt der obige Test immer die Warnung aus.

Unabhängig davon, wie jest offene Griffe unter der Haube erkennt, werden Griffe, die absichtlich von Promise.race absichtlich offen gelassen wurden, nicht berücksichtigt. Dieser Anwendungsfall fällt definitiv unter die falsch-positive Kategorie. Ich bin nicht sicher, ob dieses falsch-positive Problem behoben werden kann, aber vielleicht hat einer der Entwickler eine geniale Lösung dafür.

Im Moment bleibe ich wie alle anderen bei --forceExit .

Bearbeiten:
Gerade gefunden, scheint es tatsächlich ein tieferes NodeJS / V8-Problem zu sein https://github.com/nodejs/node/issues/24321

Für alle anderen, die von Firestore-Tests hierher kommen, funktioniert dies für mich:

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

Ich habe immer noch das gleiche Problem mit Apollo & Jest. Obwohl die Option --detectOpenHandles irgendwann beendet wird, bleibt der Prozess leider noch einige Sekunden stehen (und im Gegensatz zu seinem Namen: Es werden keine Informationen darüber bereitgestellt, welche Handles noch offen sind!).

Die Verwendung von --forceExit erledigt den Job, druckt aber ärgerlich:

Jest erzwingen: Haben Sie darüber nachgedacht, --detectOpenHandles zu verwenden, um asynchrone Vorgänge zu erkennen, die nach Abschluss> aller Tests weiter ausgeführt wurden?

Eine Problemumgehung, die ich gefunden habe (und dies ist keineswegs eine Lösung!), Ist das Hinzufügen von teardown zu jest.config.js:

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

und in teardown.js verwenden Sie process.exit:

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

Ich habe auch dieses Problem. Wie kann ich es reparieren? Ich habe forceExit: true . --forceExit --detectOpenHandles --maxWorkers=10 funktioniert nicht.

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

Bearbeiten: das Problem woanders. Es ist im Testläufer, den ich benutze ...

@alusicode
Dieser hat bei mir nicht funktioniert npm test --watchAll=false
Aber es hat funktioniert, indem --watchAll=false in die Datei package.json eingefügt wurde. 👍

Mögen

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

Offizielle Dokumente: https://jestjs.io/docs/en/cli.html# --watchall

Ich habe keine Firebase verwendet, aber ich hatte das gleiche Problem mit meinen Workflow-Skripten. Die Verwendung von jest ohne Parameter besagte, dass einige meiner Skripte nicht ordnungsgemäß heruntergefahren wurden und ich --runInBand --detectOpenHandles . Das würde das Problem für alle meine Tests außer einem beheben (übrigens --detectOpenHandles zeigte mir nicht die Tests, die Probleme hatten).
Also fing ich an, alle Tests einzeln zu überprüfen. Ich fand heraus, dass ich für 2 Tests vergessen habe, await als ich eine asynchrone Funktion aufrief.
Nach dem Hinzufügen von Warten wurde es behoben. Obwohl ich nicht denke, dass es normal ist, dass --detectOpenHandles Probleme nicht druckt.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen