Jest: Proses lelucon tidak berhenti setelah tes terakhir selesai

Dibuat pada 18 Agu 2016  ·  60Komentar  ·  Sumber: facebook/jest

Saya mengalami masalah dengan proses Jest yang tidak selesai setelah tes terakhir selesai. Pengguna harus memaksa keluar dari proses dengan ctrl-c. Teori saya adalah bahwa tidak semua sumber daya dibersihkan secara tepat oleh penulis pengujian, tetapi idealnya Jest harus berhenti.

Secara khusus, saya menguji Firebase dengan firebase-server , menjalankan satu atau lebih server untuk setiap pengujian. Dalam aksi afterEach kita memanggil metode close untuk semua server yang dibuat pada tes terakhir, namun bahkan dengan metode ini proses Jest masih tidak berhenti.

Apakah ada cara untuk memaksa proses Jest berhenti setelah tes selesai (lulus atau gagal)? Apakah ada cara untuk mendapatkan hook afterAll untuk membersihkan semua sumber daya yang tersisa? Apakah ada cara untuk men-debug yang sebenarnya membuat proses Jest berhenti? Terima kasih.

Enhancement Help Wanted good first issue

Komentar yang paling membantu

bagi siapa pun yang membaca, Anda dapat menggunakan --forceExit flag untuk mengakses fungsi ini. 🎉

Semua 60 komentar

Kami tidak memiliki cara yang baik untuk melakukan itu sekarang. Saya akan merekomendasikan mencoba menghubungkan debugger (Chrome Inspector) untuk mencari tahu apa yang sedang terjadi. Jika Anda tahu apa yang membuat pekerjaan asinkron, Anda juga dapat berpotensi menambalnya dan melacaknya (seperti meletakkan sesuatu di sekitar Promise.prototype.then)

Apakah ada alasan pekerjaan asinkron tidak dapat ditutup paksa ketika semua afterEach / after hook telah diselesaikan?

Saya tidak tahu bagaimana Anda akan menghentikan proses asinkron yang ada jika Anda tidak mengatasinya.

Saya bermigrasi dari ava dan ini bukan masalah, jadi mungkin ada jawaban? Mungkin itu process.exit di Node.js

Kami bisa melakukan itu, saya rasa, tapi saya khawatir hal itu membuat orang tidak tergantung pada saat yang seharusnya dan mereka tidak mematikan sumber daya mereka dengan benar.

cc @dmitriiabramov bagaimana menurut anda?

Satu contoh: Saya benar-benar mengalami ini dengan Jest sendiri di mana kami memiliki proses pengamat yang berjalan lama yang tidak akan menghentikan Jest itu sendiri. Jika Jest bunuh diri selama uji coba (heh!) Saya tidak akan pernah memperhatikan masalah ini dan saya akan mengirimkan versi yang akan hang ketika orang mencoba menggunakannya.

Saya tidak yakin apakah aman untuk memaksa mematikan proses. pada saat yang sama, jika orang ingin melakukan beberapa pemrosesan pasca asinkron setelah tes selesai, mereka dapat menggunakan after all hook yang akan menunggu sampai selesai sebelum menghentikan proses.

masalah lain yang mungkin kami miliki adalah memotong aliran keluaran sebelum selesai mencetak. Kami mengalami masalah ini sebelumnya, ketika pesan kesalahan tidak memiliki cukup waktu untuk dicetak sebelum proses keluar.

Pertanyaannya adalah apakah kita bisa menemukan cara Jest untuk mengatakan "Sepertinya beberapa tes tidak beres sendiri. Inilah yang terjadi".

Sebuah after all hook dapat membantu saya di sini, tetapi saya belum melihat hal seperti itu di dokumentasi (hanya afterEach ) apakah saya melewatkan sesuatu?

Sedangkan untuk menguji pembersihan yang benar, jika Anda dapat menguji apakah _files_ selesai tepat waktu dan jika mereka tidak menggunakan fitur membagi dua untuk mengisolasi masalah (seperti di rspec).

Oke, jadi setelah penelitian lebih lanjut ini tampaknya menjadi masalah dengan Firebase itu sendiri, dan tidak ada cara untuk membersihkan dengan menelepon process.exit .

Sumber:

Semua solusi melibatkan pemanggilan process.exit secara manual. Saya takut melakukan ini dalam konteks Jest, apakah ada rekomendasi di mana harus melakukan panggilan seperti itu? Pikiran pertama saya adalah seperti:

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

… Untuk keluar satu detik setelah semua tes selesai dijalankan untuk membiarkan Jest melakukan tugasnya, namun saya tidak yakin bagaimana ini mempengaruhi mode menonton, dan jika saya benar Jest melakukan beberapa hal paralelisme mewah yang mungkin membuat ini tidak berfungsi seperti yang diharapkan. Atau, apakah ini sesuatu yang perlu Anda perbaiki di Jest dengan benar? Jika ini tampak seperti senjata api bagi sejumlah orang, mengapa tidak memasukkannya ke dalam Jest? Atau setidaknya beralih antara mode "peringatan" dan mode "bunuh".

saya akan menyukai bendera --exit atau sesuatu (bisa berupa komentar per file atau sesuatu) yang secara otomatis menutup proses saat tes selesai, mirip dengan mocha. agak menjengkelkan untuk menutup setiap koneksi secara manual di setiap file pengujian.

Saya mengalami masalah yang sama saat menjalankan tes di Codeship . Itu juga gagal di drone.io .
Secara lokal itu bekerja dengan baik.

EDIT:

  • Versi lelucon : 15.1.1
  • Lokal :

    • Node: 6.2.2

    • npm: 3.9.5

  • CodeShip :

    • Node: 6.5.0

    • npm: 3.10.3

  • Drone.io

    • Node: 0.10.26

    • npm: 1.4.3

Menurut saya, Firebase harus diperbaiki.

Saya tidak keberatan menambahkan opsi yang disebut --forceExitAfterTestRun dan itu seharusnya mudah untuk ditambahkan. Saya pikir itu hanya membutuhkan perubahan untuk keluar dari sini: https://github.com/facebook/jest/blob/master/packages/jest-cli/src/cli/index.js#L41 jika bendera diberikan terlepas dari hasil.

Tampaknya semacam kondisi balapan. Terkadang berhenti setelah menjalankan semua pengujian secara lokal terkadang tidak ...

Saya menjalankan ini juga setelah mulai menggunakan Jest untuk spesifikasi API saya di mana saya menggunakan database nyata dan bukan tiruan (maaf 😇 tapi snapshot bagus untuk ini). Saya belum dapat menyelesaikan masalah bahkan setelah menambahkan afterAll pengait untuk membersihkan koneksi yang membuat saya percaya itu beberapa bagaimana terkait dengan populasi perlengkapan saya di setupFiles , bukan yang termudah untuk di-debug.

Jasmine tampaknya memiliki opsi --forceexit jadi saya tidak akan mengeluh jika serupa juga akan mendarat dengan Jest 🙏

masalah lain - jika tes gagal, maka afterAll() tidak dipanggil, jadi tidak ada yang dibersihkan dan tidak ada yang ditutup. saya pikir --bail akan memperbaiki ini tetapi saya belum mencobanya

Jika ada yang ingin mengirim PR, ini adalah sesuatu yang dapat kami bantu dan saya uraikan detailnya di komentar saya sebelumnya :)

Saya akan mencobanya jika saya punya waktu selama akhir pekan. Jika seseorang ingin melakukannya sebelumnya, itu keren: tersenyum:

Penutupan mendukung PR yang baru saja dibuka. Kami akan melanjutkan diskusi di sana.

bagi siapa pun yang membaca, Anda dapat menggunakan --forceExit flag untuk mengakses fungsi ini. 🎉

Untuk googler: Jest tidak keluar dari Jenkins CI, sedangkan secara lokal .. --forceExit memang memperbaikinya untuk saya.

Bagi saya itu lupa menangani promise dengan .then (() => {}) - melakukan pekerjaan itu

Saya masih berjuang dengan ini. Saya menguji API dengan async dan await . Saya terhubung ke aplikasi ekspres saya dan melakukan ping ke titik akhir tetapi pengujian tidak menutup. Saya sudah mencoba menutup koneksi ke mongodb dan ke server tetapi masih terbuka. Saya hanya mengirim kembali json kosong.

Dalam kasus saya, ini akhirnya menjadi masalah Firebase. Menggunakan

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

sepertinya berhasil. Saya telah menemukan bahwa kedua baris sebenarnya diperlukan dan Anda perlu menggunakan firebaseApp yang sama yang Anda dapatkan dari .initializeApp() .

Apakah ada cara untuk menyelesaikan ini tanpa forceExit?

Jest 23 menyertakan sebuah bendera bernama --detectOpenHandles yang seharusnya menunjuk ke sumber mengapa Jest tidak dapat keluar

--detectOpenHandles mengembalikan mongoose.connect dan mongoose.model. Mencoba untuk mongoose.disconnect di afterAll menimbulkan kesalahan mongo Topology hancur.

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

@elkhan sudahkah kamu mencari cara untuk memecahkan masalah luwak?

Setelah menambahkan --detectOpenHandles , Jest tidak hanya menyelesaikan pengujian saya dan juga tidak menunjukkan apa pun yang sebenarnya memblokir Jest yang aneh. Sepertinya bug.

Bagi saya, --forceExit menyelesaikan masalah, pada saat yang sama saya menggunakan --detectOpenHandles tetapi tidak mendeteksi apa pun (baik secara lokal maupun di CircleCI). Saya juga menjalankan dengan --runInBand .

Bagi saya, menghapus --runInBand menyelesaikannya.

--forceExit memecahkan masalah untuk saya juga saat menggunakan shippable ... Mencoba --detectOpenHandles tetapi tidak memberikan hasil apa pun dan tetap menyebabkan bangunan macet

Menambahkan --detectOpenHandles memperbaiki masalah yang aneh ini.

Node: v8.12.0
Lelucon: v23.6.0

Menambahkan --detectOpenHandles atau --forceExit tidak memperbaiki masalah saya saat menjalankan Codeship.

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

Node: v8.12.0
Lelucon: v23.6.0

@sibelius cara untuk menghindari masalah ini adalah dengan mematikan fungsi init model

const mongoose = require('mongoose');

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

Ini akan menghentikan Jest untuk mengeluh tentang model, meskipun indeks tidak akan dibuat

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 tes lulus, tetapi kode dalam .then atau .catch tidak berjalan !!
ada ide?

@alexpchin Inilah cara saya menyelesaikannya:

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

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

Dengan NestJ saya harus menambahkan

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

Kami menemukan bahwa masalah ini disebabkan oleh proses lelucon yang kehabisan memori. Menambahkan --maxWorkers=10 memperbaiki masalah kami.

Saya menambahkan penyebab ini mungkin seseorang yang bertanya-tanya tentang masalah ini mungkin memiliki alasan untuk ini seperti yang saya miliki.
Saya menggunakan Jest dalam Travis untuk menguji aplikasi NodeJS dan travis terus menunggu sampai waktu tunggu langsung setelah Jest. Tampaknya Jest tidak menutup diri.
Setelah banyak percobaan, saya menemukan alasannya menggunakan lelucon dengan JSDom.
Saya memiliki baris berikut di file jest.config.js :

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

Yang menyebabkan JSDom memuat dan seharusnya tidak menutup semua sumber daya dengan anggun dan membuat Jest tetap hidup.

Saya menyelesaikannya dengan menghapus garis - namun Jest kemudian akan gagal dengan kesalahan berikut, lihat ini :

SecurityError: localStorage is not available for opaque origins

Untuk mengatasinya saya menambahkan yang berikut ini ke jest.config.js :

  'testEnvironment': 'node',

Saya menambahkan ini karena mungkin seseorang yang bertanya-tanya tentang masalah ini mungkin memiliki alasan untuk ini seperti yang saya miliki.
Saya menggunakan Jest dalam Travis untuk menguji aplikasi NodeJS dan travis terus menunggu sampai waktu tunggu langsung setelah Jest. Tampaknya Jest tidak menutup diri.
Setelah banyak percobaan, saya menemukan alasannya menggunakan lelucon dengan JSDom.
Saya memiliki baris berikut di file jest.config.js :

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

Yang menyebabkan JSDom dimuat dan seharusnya tidak menutup semua sumber daya dengan baik dan membuat Jest tetap hidup.

Saya menyelesaikannya dengan menghapus garis - namun Jest kemudian akan gagal dengan kesalahan berikut, lihat ini :

SecurityError: localStorage is not available for opaque origins

Untuk mengatasinya saya menambahkan yang berikut ini ke jest.config.js :

  'testEnvironment': 'node',

Semoga bisa membantu siapa saja.

--forceExit --detectOpenHandles --maxWorkers = 10

melakukannya untuk kita

node: 8.11.3
lelucon 23.6.0

Dengan NestJ saya harus menambahkan

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

Tinggalkan ini di sini untuk orang-orang NestJS:
Dengan NestJS, saya menemukan bahwa jawaban di atas berhasil.
Apa yang TIDAK berhasil adalah sebagai berikut:

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

bagi saya, --forceExit --maxWorkers=10 yang berfungsi (saya menggunakan Ubuntu 18.04, menggunakan [email protected])

Dalam kasus saya, menggunakan NodeJS 10 atau 11 memperbaiki masalah, tetapi masih ada dengan Node 6 ou Node 8. tidak ada yang ditampilkan saat menggunakan opsi --detectOpenHandles , dan --forceExit memperbaiki masalah juga.

1 orang lagi di sini (seperti @motss dan @seanlindo) mengamati bahwa _ "Jest tidak keluar satu detik setelah uji coba selesai." _ Terjadi hanya ketika --detectOpenHandles tidak digunakan.

[email protected]

Pengujian gagal secara konsisten tanpa --detectOpenHandles tetapi lulus dan tidak menampilkan pegangan terbuka saat menjalankan dengan --detectOpenHandles .

Mesin / penampung yang menjalankan pengujian memiliki dua inti, tetapi secara default, pengujian dijalankan dengan maxWorkers=1

Ketika saya menambahkan flag --detectOpenHandles dan melihat config / globalConfig menggunakan flag --debug , nilai detectOpenHandles adalah perbedaan _only_ ...

Jika saya menjalankan tes with --runInBand --detectOpenHandles masih lulus dengan baik.

Saya dapat menjalankan menggunakan salah satu dari berikut ini untuk menyelesaikan tes dengan sukses tanpa menunjukkan kesalahan "... tidak keluar ...":

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

Mengatasinya dengan maxWorkers=2 untuk saat ini, tetapi itu adalah pengamatan saya, hanya untuk siapa saja yang mencari di masa depan ...

_Edit: Detail tambahan: ini hanya memengaruhi lingkungan CI saya, yang merupakan container buruh pelabuhan DARI alpine: 3.7 menjalankan node v8.9.3. Saya tidak dapat mereproduksi dengan --maxWorkers=1 pada mesin dev saya_

Mengonfirmasi bahwa saya mendapatkan kesalahan ini sekarang. Menggunakan --maxWorkers=10 sepertinya bisa mengatasi masalah.

Jadi .... Saya bertengkar dengan ini untuk beberapa waktu (menggunakan travis ci, coverall dan skrip ketik).
Itu akan berakhir dengan hang dan menghasilkan build yang gagal (tetapi hanya dengan Travis CI).

Setelah banyak trial and error, saya menemukan apa yang memperbaikinya untuk saya adalah bahwa saya menambahkan jalur eksplisit ke tes.

Itu gagal dengan skrip npm

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

Dan lulus (in travis ci) dengan:

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

Jika Anda menggunakan buruh pelabuhan dengan gambar UBI Redhat dan create-react-app pastikan Anda menyetel CI=true sebelum menjalankan npm test

Desember 2019. Mengalami masalah ini HANYA di Travis. Tes lulus secara lokal. Perbaikan @qopqopqop berhasil untuk saya. Menggunakan Jest versi 24.9.0

Saya hanya menemukan kesalahan ini ketika proyek kami mulai menambahkan komponen baru yang menggunakan hooks dan testing-library. Saya pikir mungkin ada beberapa gesekan antara Jest, testing-library, dan hook React karena ini semua adalah teknologi baru. Proyek-proyek ini masih mempelajari cara bermain dengan baik satu sama lain. ATAU, kami dapat menulis komponen fungsional yang sangat bermasalah yang menggunakan pengait secara tidak benar. :-)

Saya masih memiliki masalah ini. Saya tidak bisa keluar dari pengujian, ini membuat npm test gagal untuk semua aplikasi saya. ada petunjuk?

@koooge Dapatkah Anda memposting contoh apa yang tidak berhasil untuk Anda?

Untuk membuat tes keluar dengan 0 setelah semua tes lulus, Anda harus memasukkan --watchAll = false
seperti npm run test - --watchAll = false

ini berhasil untuk saya

Untuk membuat ini berfungsi dengan Firebase, saya harus melakukan ini:

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

Saya telah memperbaikinya menggunakan opsi:

--forceExit

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

Jadi saya mengalami masalah ini juga. Sangat menjengkelkan melihat pesan peringatan A worker process has failed to exit gracefully and has been force exited... ketika saya tahu saya menangani semua panggilan async dengan benar. Saya menjalankan pengujian saya dengan --detectOpenHandles tetapi tidak ada yang muncul. Setelah beberapa penelitian, saya menemukan bahwa pelakunya adalah Promise.race .

Saya menggunakan pustaka utilitas promise asli (https://github.com/blend/promise-utils) dan membungkus beberapa panggilan API eksternal saya di utilitas timeout . Utilitas ini pada gilirannya menggunakan asli Promise.race .

Saya mengeluarkan kode itu dan membuat kasus uji sederhana untuk mengonfirmasi temuan saya.

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

Dengan asumsi pengaturan waktu tunggu kasus uji Anda adalah default, pengujian di atas akan selalu memberikan peringatan.

Apa pun cara yang digunakan jest untuk mendeteksi gagang terbuka di bawah kap, itu tidak mempertimbangkan gagang yang dibiarkan terbuka secara sengaja oleh Promise.race . Kasus penggunaan ini pasti termasuk dalam kategori positif palsu. Saya tidak yakin positif palsu ini dapat diperbaiki, tetapi mungkin salah satu pengembang memiliki solusi yang cerdik untuk ini.

Untuk saat ini, saya tetap menggunakan --forceExit seperti orang lain.

Edit:
Baru saja menemukan ini, sepertinya ini memang masalah nodejs / v8 yang lebih dalam https://github.com/nodejs/node/issues/24321

Untuk siapa pun yang datang ke sini dari tes Firestore, ini berfungsi untuk saya:

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

Saya masih mengalami masalah yang sama saat menggunakan Apollo & Jest. Sayangnya, meskipun opsi --detectOpenHandles akhirnya keluar, itu masih membuat proses tertunda selama beberapa detik lagi (dan bertentangan dengan namanya: ini tidak memberikan informasi tentang pegangan mana yang masih terbuka!).

Menggunakan --forceExit melakukan pekerjaan itu tetapi mencetak dengan menjengkelkan:

Keluar Paksa Jest: Pernahkah Anda mempertimbangkan untuk menggunakan --detectOpenHandles untuk mendeteksi operasi asinkron yang terus berjalan setelah> semua tes selesai?

Solusi yang saya temukan (dan ini sama sekali bukan solusi!) Adalah menambahkan teardown ke jest.config.js:

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

dan di teardown.js gunakan process.exit:

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

Saya juga punya masalah ini. Bagaimana cara memperbaikinya? Saya telah menyetel forceExit: true . --forceExit --detectOpenHandles --maxWorkers=10 tidak bekerja.

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

Edit: masalah di tempat lain. Di dalam test-runner yang saya gunakan ...

@tokopedia
Yang ini tidak berhasil untuk saya npm test --watchAll=false
Tapi itu berhasil dengan menambahkan --watchAll=false dalam file package.json. 👍

Suka

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

Dokumen resmi: https://jestjs.io/docs/en/cli.html# --watchall

Tidak menggunakan firebase tetapi saya memiliki masalah yang sama pada skrip alur kerja saya. menggunakan jest tanpa parameter mengatakan beberapa skrip saya tidak bisa dimatikan dengan baik dan saya harus menggunakan --runInBand --detectOpenHandles . Itu akan memperbaiki masalah untuk semua tes saya kecuali satu (btw --detectOpenHandles tidak menunjukkan tes yang bermasalah).
Jadi saya mulai memeriksa semua tes satu per satu. Saya menemukan bahwa untuk 2 tes saya lupa menggunakan await ketika saya memanggil fungsi async.
Setelah menambahkan menunggu itu diperbaiki. Meskipun saya tidak berpikir itu normal bahwa --detectOpenHandles tidak mencetak masalah.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat