Jest: لا يتم إنهاء عملية الدعابة بعد اكتمال الاختبار الأخير

تم إنشاؤها على ١٨ أغسطس ٢٠١٦  ·  60تعليقات  ·  مصدر: facebook/jest

أواجه مشكلات في عدم اكتمال عملية Jest بعد اكتمال الاختبار الأخير. سيتعين على المستخدم فرض إنهاء العملية باستخدام ctrl-c. نظريتي هي أنه لا يتم تنظيف جميع الموارد بشكل مناسب من قبل مؤلفي الاختبار ، ولكن من الناحية المثالية ، يجب ترك Jest على أي حال.

على وجه التحديد ، أنا أختبر Firebase باستخدام firebase-server ، حيث أقوم بتدوير خادم أو أكثر لكل اختبار. في إجراء afterEach نطلق على طريقة close لجميع الخوادم التي تم إنشاؤها في الاختبار الأخير ، ولكن حتى مع هذه الطريقة ، لا تزال عملية Jest لا تنتهي.

هل هناك طريقة لإجبار عملية Jest على الإنهاء بمجرد انتهاء الاختبارات (النجاح أو الفشل)؟ هل هناك طريقة للحصول على ربط afterAll لتنظيف جميع الموارد المتبقية؟ هل هناك طريقة لتصحيح ما يمنع بالضبط عملية Jest من الإقلاع؟ شكر.

Enhancement Help Wanted good first issue

التعليق الأكثر فائدة

لأي شخص يقرأ ، يمكنك استخدام العلم --forceExit للوصول إلى هذه الوظيفة. 🎉

ال 60 كومينتر

ليس لدينا طريقة جيدة للقيام بذلك الآن. أوصي بمحاولة ربط مصحح أخطاء (Chrome Inspector) لمعرفة ما يجري. إذا كنت تعرف سبب إنشاء العمل غير المتزامن ، فيمكنك أيضًا تصحيح القرد وتتبعه (مثل وضع شيء حول Promise.prototype. ثم)

هل هناك سبب لا يمكن فرض إنهاء العمل غير المتزامن عندما يتم حل جميع الخطافات afterEach / after ؟

لا أعرف كيف ستقتل العمليات غير المتزامنة الحالية إذا لم يكن لديك أي سيطرة عليها.

لقد هاجرت من ava ولم تكن هذه مشكلة ، فربما توجد إجابة؟ ربما هذا process.exit في Node.js

أعتقد أنه يمكننا القيام بذلك ، لكنني أخشى أن يترك الناس غير معلقين عندما ينبغي ذلك ، ولا يغلقون مواردهم بشكل صحيح.

cc @ dmitriiabramov ما رأيك؟

أحد الأمثلة: لقد واجهت هذا بالفعل مع Jest بنفسي حيث كان لدينا عملية مراقبة طويلة الأمد لن تنهي Jest نفسها. إذا كان Jest قد قتل نفسه أثناء التشغيل التجريبي (هيه!) لما لاحظت المشكلة مطلقًا وكنت سأشحن إصدارًا سيتعطل عندما يحاول الناس استخدامه.

لست متأكدًا مما إذا كان من الآمن قتل العملية بالقوة. في الوقت نفسه ، إذا أراد الأشخاص القيام ببعض المعالجة اللاحقة غير المتزامنة بعد الانتهاء من الاختبارات ، فيمكنهم استخدام الخطاف after all الذي سينتظر حتى ينتهي قبل إنهاء العملية.

المشكلة الأخرى التي قد تكون لدينا هي قطع تيار الإخراج قبل أن ينتهي من الطباعة. واجهتنا هذه المشكلة من قبل ، عندما لا يكون لرسائل الخطأ الوقت الكافي للطباعة قبل انتهاء العملية.

السؤال هو ما إذا كان بإمكاننا اكتشاف طريقة لجست ليقول "يبدو أن بعض الاختبارات لا تنظف بعد نفسها. هذا ما يجري".

يمكن أن يساعدني الخطاف after all هنا ، لكنني لم أر مثل هذا الشيء في الوثائق (فقط afterEach ) هل فاتني أي شيء؟

بالنسبة لاختبار عمليات التنظيف الصحيحة ، إذا كان بإمكانك اختبار ما إذا كانت _الملفات _ قد اكتملت في الوقت المحدد وما إذا كانت لا تستخدم ميزة bisect لعزل المشكلة (كما هو الحال في rspec).

حسنًا ، بعد إجراء المزيد من البحث ، يبدو أن هذا يمثل مشكلة في Firebase نفسه ، ولا توجد طريقة للتنظيف باستثناء استدعاء process.exit .

مصادر:

تتضمن جميع الحلول استدعاء process.exit يدويًا. أخشى أن أفعل هذا في سياق الدعابة ، هل هناك توصية بشأن مكان إجراء مثل هذه المكالمة؟ كان فكرتي الأولى شيئًا مثل:

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

... للخروج من ثانية واحدة بعد انتهاء جميع الاختبارات للسماح لـ Jest بالقيام بعملها ، لكنني لست متأكدًا من كيفية تأثير ذلك على وضع الساعة ، وإذا كنت على حق ، فإن Jest يقوم ببعض الأشياء التوازي الهائلة التي قد تجعل هذا لا يعمل كما هو متوقع. بدلاً من ذلك ، هل سيكون هذا شيئًا تحتاج إلى إصلاحه في Jest بشكل صحيح؟ إذا كان هذا يبدو وكأنه مسدس قدم لعدد من الأشخاص ، فلماذا لا تضعه في Jest؟ أو على الأقل التبديل بين وضع "التحذير" ووضع "القتل".

أحب علامة --exit أو شيئًا ما (قد يكون تعليقًا لكل ملف أو شيء ما) الذي يغلق العمليات تلقائيًا عند اكتمال الاختبارات ، على غرار mocha. من المزعج قليلاً إغلاق كل اتصال يدويًا في كل ملف اختبار.

أواجه نفس المشكلة عندما أجري اختبارات في Codeship . كما أنه فشل في drone.io .
محليا يعمل بشكل صحيح بالرغم من ذلك.

تعديل:

  • إصدار الدعابة : 15.1.1
  • محلي :

    • العقدة: 6.2.2

    • npm: 3.9.5

  • كود السفينة :

    • العقدة: 6.5.0

    • npm: 3.10.3

  • Drone.io

    • العقدة: 0.10.26

    • npm: 1.4.3

يبدو لي أنه يجب إصلاح Firebase.

ليس لدي أي تحفظات على إضافة خيار يسمى --forceExitAfterTestRun ويجب أن يكون من السهل إضافته. أعتقد أنه يتطلب فقط تغييرًا للخروج من هنا: https://github.com/facebook/jest/blob/master/packages/jest-cli/src/cli/index.js#L41 إذا تم تقديم العلم بغض النظر عن نتيجة.

يبدو أنه حالة سباق من نوع ما. في بعض الأحيان يتم إنهاء العمل بعد إجراء جميع الاختبارات محليًا في بعض الأحيان لا ...

أنا أقوم بتشغيل هذا أيضًا بعد البدء في استخدام Jest لمواصفات API الخاصة بي حيث أستخدم قاعدة بيانات حقيقية بدلاً من mocks (آسف ، لكن اللقطات رائعة لهذا). لقد تمكنت حتى الآن من حل المشكلة حتى بعد إضافة خطافات afterAll لتنظيف الاتصالات مما يقودني إلى الاعتقاد بأنها مرتبطة ببعض التركيبات في setupFiles ، ليس من الأسهل تصحيحه.

يبدو أن ياسمين لديها خيار --forceexit لذا لن أشكو إذا كان هذا هو الحال أيضًا لـ Jest 🙏

مشكلة أخرى - إذا فشل الاختبار ، فلن يتم استدعاء afterAll() ، لذلك لا يتم تنظيف أي شيء ولا يتم إغلاق أي شيء. أعتقد أن --bail سيصلح هذا لكني لم أحاول ذلك بعد

إذا كان أي شخص يرغب في إرسال PR ، فهذا شيء يمكننا استخدام بعض المساعدة فيه وقد أوجزت التفاصيل في تعليقي السابق :)

سأعطيها فرصة إذا حصلت على بعض الوقت خلال عطلة نهاية الأسبوع. إذا أراد شخص ما القيام بذلك قبل ذلك ، فسيكون رائعًا: ابتسم:

إغلاق لصالح العلاقات العامة التي تم فتحها للتو. سنواصل المناقشة هناك.

لأي شخص يقرأ ، يمكنك استخدام العلم --forceExit للوصول إلى هذه الوظيفة. 🎉

لموظفي Google: Jest لا يخرج من Jenkins CI ، بينما يحدث محليًا .. --forceExit بالفعل بإصلاحه بالنسبة لي.

بالنسبة لي كان نسيان التعامل مع الوعد مع. ثم (() => {}) - أنجز المهمة

ما زلت أعاني من هذا. أنا أختبر واجهة برمجة تطبيقات باستخدام async و await . أقوم بالاتصال بتطبيقي السريع وأجري ping على نقطة نهاية ولكن الاختبار لا يغلق. لقد حاولت إغلاق الاتصال بـ mongodb والخادم لكنه لا يزال مفتوحًا. أنا فقط أرسل مرة أخرى json فارغة.

في حالتي ، انتهى الأمر بكونه مشكلة في Firebase. باستخدام

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

يبدو أن تفعل خدعة. لقد وجدت أن كلا السطرين ضروريان بالفعل وأنك بحاجة إلى استخدام نفس firebaseApp الذي تحصل عليه في الأصل من .initializeApp() .

هل هناك طريقة لحل هذا بدون forceExit؟

يتضمن Jest 23 علامة تسمى --detectOpenHandles والتي يجب أن تشير إلى مصدر سبب عدم قدرة Jest على الخروج

--detectOpenHandles تُعيد mongoose.connect و mongoose.model. محاولة النمس. قطع الاتصال في afterAll يثير mongo خطأ طوبولوجيا دمرت.

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

@ elkhan هل تعرف كيفية حل مشاكل النمس؟

بعد إضافة --detectOpenHandles ، لم يكمل Jest اختباراتي فحسب ، كما أنه لا يعرض أي شيء يحظر Jest وهو أمر غريب. يبدو وكأنه حشرة.

بالنسبة لي ، يحل --forceExit المشكلة ، وفي نفس الوقت أستخدم --detectOpenHandles لكنه لا يكتشف شيئًا (محليًا وعلى CircleCI). أنا أعمل أيضًا بـ --runInBand .

بالنسبة لي ، أدت إزالة --runInBand حل المشكلة.

--forceExit يحل المشكلة أيضًا عند استخدام shippable ... حاولت --detectOpenHandles لكن لم تعط أي نتائج وما زلت تسببت في توقف البناء

إضافة --detectOpenHandles يصلح المشكلة ، وهذا أمر غريب.

العقدة: v8.12.0
دعابة: v23.6.0

لا تؤدي إضافة --detectOpenHandles أو --forceExit حل المشكلة بالنسبة لي عند التشغيل على Codeship.

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

العقدة: v8.12.0
دعابة: v23.6.0

sibelius طريقة لتجنب هذه المشكلة عن طريق كتم وظيفة init للنموذج

const mongoose = require('mongoose');

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

سيؤدي هذا إلى منع Jest من الشكوى من النماذج ، على الرغم من أنه لن يتم إنشاء الفهارس

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 تم اجتياز الاختبارات ، لكن الكود الموجود في .then أو .catch لا يعمل !!
أيه أفكار؟

alexpchin إليك كيف حللت ذلك:

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

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

مع NestJs كان علي أن أضيف

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

وجدنا أن سبب هذه المشكلة هو نفاد الذاكرة من عملية المزاح. أدت إضافة --maxWorkers=10 إصلاح المشكلة بالنسبة لنا.

أقوم بإضافة هذا السبب ، فربما يكون هناك شخص ما يتساءل في هذه المشكلة هو السبب في ذلك كما فعلت.
كنت أستخدم Jest داخل Travis لاختبار تطبيق NodeJS وظل travis معلقًا حتى انتهاء المهلة مباشرة بعد Jest. يبدو Jest لم يكن يغلق.
بعد عدة محاولات اكتشفت أن السبب كان استخدام المزاح مع JSDom.
كان لدي السطر التالي في ملف jest.config.js :

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

مما تسبب في تحميل JSDom ومن المفترض أنه لم يغلق جميع الموارد بأمان والحفاظ على Jest على قيد الحياة.

لقد قمت بحلها عن طريق إزالة الخط - ولكن Jest ستفشل بعد ذلك مع الخطأ التالي ، انظر هذا :

SecurityError: localStorage is not available for opaque origins

لحلها أضفت ما يلي إلى jest.config.js :

  'testEnvironment': 'node',

آمل أن يساعد ذلك أي شخص ، فأنا أضيف هذا السبب ، فربما يكون هناك من يتساءل في هذه المشكلة سبب ذلك كما فعلت.
كنت أستخدم Jest داخل Travis لاختبار تطبيق NodeJS وظل travis معلقًا حتى انتهاء المهلة مباشرة بعد Jest. يبدو Jest لم يكن يغلق.
بعد عدة محاولات اكتشفت أن السبب كان استخدام المزاح مع JSDom.
كان لدي السطر التالي في ملف jest.config.js :

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

مما تسبب في تحميل JSDom ومن المفترض أنه لم يغلق جميع الموارد بأمان والحفاظ على Jest على قيد الحياة.

لقد قمت بحلها عن طريق إزالة الخط - لكن Jest ستفشل بعد ذلك مع الخطأ التالي ، انظر إلى هذا :

SecurityError: localStorage is not available for opaque origins

لحلها أضفت ما يلي إلى jest.config.js :

  'testEnvironment': 'node',

أتمنى أن يساعد ذلك أي شخص.

--forceExit --detectOpenHandles --maxWorkers = 10

فعل ذلك من أجلنا

العقدة: 8.11.3
jest 23.6.0

مع NestJs كان علي أن أضيف

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

مجرد ترك هذا هنا لأفراد NestJS:
مع NestJS ، اكتشفت أن الإجابة أعلاه تعمل.
ما لا يعمل هو ما يلي:

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

بالنسبة لي ، هذا هو --forceExit --maxWorkers=10 الذي يعمل (أنا على Ubuntu 18.04 ، باستخدام [email protected])

في حالتي ، فإن استخدام NodeJS 10 أو 11 يصلح المشكلة ، لكنه لا يزال موجودًا مع Node 6 ou Node 8. لا يتم عرض أي شيء عند استخدام الخيار --detectOpenHandles ، و --forceExit يصلح المشكلة أيضًا.

+1 شخص آخر هنا (مثل motss و seanlindo ) يلاحظ أن _ "Jest لم يخرج بعد ثانية واحدة من اكتمال التشغيل التجريبي." _ يحدث فقط عندما لا يتم استخدام --detectOpenHandles .

[email protected]

تفشل الاختبارات باستمرار بدون --detectOpenHandles ولكنها تمر ولا تظهر أي مقابض مفتوحة عند الجري باستخدام --detectOpenHandles .

تحتوي الآلة / الحاوية التي تشغل الاختبارات على مركزين ، ولكن افتراضيًا ، يتم تشغيل الاختبارات باستخدام maxWorkers=1

عندما أقوم بإضافة علامة --detectOpenHandles وإلقاء نظرة على config / globalConfig باستخدام علامة --debug ، فإن detectOpenHandles هي الفرق _ only_ ...

إذا قمت بتشغيل with --runInBand --detectOpenHandles الاختبارات لا تزال تمر بشكل جيد.

يمكنني تشغيل أي مما يلي لإنهاء الاختبارات بنجاح دون إظهار الخطأ "... لم يخرج ...":

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

أعمل على حل المشكلة باستخدام maxWorkers=2 في الوقت الحالي ، ولكن هذه هي ملاحظاتي ، فقط لأي شخص يبحث في المستقبل ...

_Edit: تفاصيل إضافية: هذا يؤثر فقط على بيئة CI الخاصة بي ، وهي حاوية عامل إرساء من جبال الألب: 3.7 عقدة تشغيل v8.9.3. لا يمكنني إعادة الإنتاج باستخدام --maxWorkers=1 على جهاز التطوير الخاص بي_

تأكيد تلقيت هذا الخطأ الآن. يبدو أن استخدام --maxWorkers=10 يصلح المشكلة.

لذلك .... كنت أقاتل مع هذا لبعض الوقت (باستخدام travis ci ، المآزر والطباعة المطبوعة).
سينتهي الأمر بالتعليق وإنتاج بنية فاشلة (ولكن فقط مع Travis CI).

بعد الكثير من التجارب والخطأ ، وجدت أن ما تم إصلاحه بالنسبة لي هو أنني أضفت مسارًا واضحًا للاختبارات.

فشل مع البرنامج النصي npm

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

ومرت (في travis ci) بـ:

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

إذا كنت تستخدم عامل إرساء مع صورة Redhat UBI و create-react-app فتأكد من تعيين CI=true قبل تشغيل npm test

ديسمبر 2019. ركض في هذه المسألة فقط على ترافيس. الاختبارات تمر محليا. نجح إصلاح

لقد واجهت هذا الخطأ فقط عندما بدأ مشروعنا في إضافة مكونات جديدة تستخدم الخطافات ومكتبة الاختبار. أعتقد أنه قد يكون هناك بعض الاحتكاك بين Jest ، ومكتبة الاختبار ، وخطافات React لأن هذه كلها تقنيات جديدة. لا تزال هذه المشاريع تتعلم كيفية اللعب بشكل جيد مع بعضها البعض. أو ، يمكن أن نكتب بالفعل مكونات وظيفية عربات التي تجرها الدواب التي تستخدم الخطافات بشكل غير صحيح. :-)

لا يزال لدي هذه المشكلة. لا يمكنني الخروج من الاختبار ، وهذا يجعل npm test يفشل لجميع تطبيقي. أي فكرة؟

koooge هل يمكنك نشر مثال لما لا يصلح لك؟

لجعل الاختبار يخرج بالرقم 0 بعد اجتياز جميع الاختبارات ، يجب أن تجتاز --watchAll = false
مثل npm run test - --watchAll = false

هذا عمل معي

لإنجاز هذا العمل مع Firebase ، كان علي القيام بذلك:

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

لقد أصلحته باستخدام الخيار:

--forceExit

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

لذلك واجهت هذه المشكلة أيضًا. كان من المزعج رؤية رسالة التحذير A worker process has failed to exit gracefully and has been force exited... عندما علمت أنني كنت أتعامل مع جميع مكالماتي async بشكل صحيح. أجريت اختباراتي باستخدام --detectOpenHandles ولكن لم يظهر شيء. بعد إجراء بعض البحث ، اكتشفت أن الجاني كان Promise.race .

أستخدم مكتبة أدوات مساعدة أصلية (https://github.com/blend/promise-utils) وألّف بعض استدعاءات API الخارجية في الأداة المساعدة timeout . تستخدم هذه الأداة بدورها Promise.race الأصلي.

لقد سحبت هذا الرمز وأنشأت حالة اختبار بسيطة لتأكيد النتائج التي توصلت إليها.

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

بافتراض أن إعدادات مهلة حالة الاختبار الخاصة بك هي إعدادات افتراضية ، فإن الاختبار أعلاه سيعطي تحذيرًا دائمًا.

مهما كانت الطريقة التي يستخدمها jest لاكتشاف المقابض المفتوحة تحت الغطاء ، فإنها لا تأخذ في الاعتبار المقابض التي تُركت مفتوحة عن قصد بمقدار Promise.race . تندرج حالة الاستخدام هذه بالتأكيد ضمن فئة إيجابية كاذبة. لست متأكدًا من أن هذه النتائج الإيجابية الزائفة قابلة للإصلاح ، ولكن ربما يكون لدى أحد المطورين حل مبتكر لهذا الأمر.

في الوقت الحالي ، أنا متمسك بـ --forceExit مثل أي شخص آخر.

تعديل:
وجدت هذا للتو ، يبدو أنه بالفعل مشكلة أعمق في nodejs / v8 https://github.com/nodejs/node/issues/24321

بالنسبة لأي شخص آخر قادم إلى هنا من اختبارات Firestore ، فهذا يناسبني:

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

ما زلت أواجه نفس المشكلة باستخدام Apollo & Jest. لسوء الحظ ، على الرغم من أن الخيار --detectOpenHandles ينتهي أخيرًا ، فإنه لا يزال يجعل العملية معلقة لبضع ثوان أخرى (وفي تناقض مع اسمها: لا يوفر معلومات حول المقابض التي لا تزال مفتوحة!).

استخدام --forceExit يقوم بالمهمة ولكنه يطبع بشكل مزعج:

فرض الخروج من Jest: هل فكرت في استخدام --detectOpenHandles لاكتشاف العمليات غير المتزامنة التي ظلت تعمل بعد> انتهاء جميع الاختبارات؟

الحل الذي وجدته (وهذا ليس حلاً بأي حال من الأحوال!) هو إضافة teardown إلى jest.config.js:

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

وفي teardown.js استخدم process.exit:

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

انا ايضا لدي هذه المشكلة كيف يمكنني إصلاح ذلك؟ لقد قمت بتعيين forceExit: true . --forceExit --detectOpenHandles --maxWorkers=10 لا يعمل.

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

تحرير: القضية في مكان آخر. إنه في عداء الاختبار الذي أستخدمه ...

alusicode
هذا لم يعمل لي npm test --watchAll=false
لكنها نجحت بإضافة --watchAll=false في ملف package.json. 👍

مثل

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

المستندات الرسمية: https://jestjs.io/docs/en/cli.html# --watchall

لا أستخدم Firebase ولكن لدي نفس المشكلة في البرامج النصية لسير العمل. باستخدام jest بدون معلمات قال إن بعض البرامج النصية الخاصة بي لم يتم إغلاقها بأمان ويجب أن أستخدم --runInBand --detectOpenHandles . ومن شأن ذلك أن يحل المشكلة لجميع من بلدي التجارب باستثناء واحد (راجع للشغل --detectOpenHandles لم تدلني على الاختبارات التي لديها مشاكل).
لذلك بدأت في فحص جميع الاختبارات واحدًا تلو الآخر. اكتشفت أنه في اختبارين نسيت استخدام await عندما كنت أستدعي وظيفة غير متزامنة.
بعد إضافة الانتظار تم إصلاحه. على الرغم من أنني لا أعتقد أنه من الطبيعي أن --detectOpenHandles لا يطبع المشكلات.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات