أواجه مشكلات في عدم اكتمال عملية Jest بعد اكتمال الاختبار الأخير. سيتعين على المستخدم فرض إنهاء العملية باستخدام ctrl-c. نظريتي هي أنه لا يتم تنظيف جميع الموارد بشكل مناسب من قبل مؤلفي الاختبار ، ولكن من الناحية المثالية ، يجب ترك Jest على أي حال.
على وجه التحديد ، أنا أختبر Firebase باستخدام firebase-server
، حيث أقوم بتدوير خادم أو أكثر لكل اختبار. في إجراء afterEach
نطلق على طريقة close
لجميع الخوادم التي تم إنشاؤها في الاختبار الأخير ، ولكن حتى مع هذه الطريقة ، لا تزال عملية Jest لا تنتهي.
هل هناك طريقة لإجبار عملية Jest على الإنهاء بمجرد انتهاء الاختبارات (النجاح أو الفشل)؟ هل هناك طريقة للحصول على ربط afterAll
لتنظيف جميع الموارد المتبقية؟ هل هناك طريقة لتصحيح ما يمنع بالضبط عملية Jest من الإقلاع؟ شكر.
ليس لدينا طريقة جيدة للقيام بذلك الآن. أوصي بمحاولة ربط مصحح أخطاء (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 .
محليا يعمل بشكل صحيح بالرغم من ذلك.
تعديل:
يبدو لي أنه يجب إصلاح 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 خطأ طوبولوجيا دمرت.
@ 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
.
تفشل الاختبارات باستمرار بدون --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();
});
لذلك واجهت هذه المشكلة أيضًا. كان من المزعج رؤية رسالة التحذير 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
لا يطبع المشكلات.
التعليق الأكثر فائدة
لأي شخص يقرأ ، يمكنك استخدام العلم
--forceExit
للوصول إلى هذه الوظيفة. 🎉