Open jrr opened 5 years ago
https://jestjs.io/docs/en/configuration#setupfilesafterenv-array
But AFAIK there's no option to run something before the worker is closed. I'd find such a feature useful, especially for generating database namespaces to run tests in isolation etc., like with Redis you mentioned.
For more complex use cases, a custom environment is probably more well suited. We do this e.g. for setting up and tearing down a database connection.
@jeysal by "custom environment", you mean the thing specified via testEnvironment, right? Does that give you an opportunity for setup/teardown per-worker, or only per-file?
Well, not exactly per-worker. You can use JEST_WORKER_ID
to distinguish between workers for using distinct databases, but I can see how that might not be enough in some use cases, performance-wise.
A big +1 for this 👍🏻
I'm from the core team maintaining Detox (who have already introduced enhancements to Jest
, in the past), and we would also really appreciate this kind of support. Our use case is effectively identical, up to the point that instead of databases, we have Android/iOS emulators as the resource in question. We already have the means to bring up emulators on a per-worker basis, but we lack the ability to clean up efficiently (i.e. immediately when a worker is no longer required). Things become even more prominent when these emulators are rented from external SaaS providers such as Genymotion cloud: You literally pay for rent time, and hence must painfully optimize it.
Have any of you folks found a way to emulate this feature using the existing setup / teardown primitives?
@airhorns I've tried doing so by registering a process.on('beforeExit', () => {...})
callback in a worker's context (reference).
Unfortunately, empirically it seems that Jest keeps all workers alive right until the last one is done, so there's no added value compared to subscribing a global-teardown listener (which is the obvious alternative).
In addition, it seems Jest doesn't approve asynchronous work done past the time it expects everything to be torn down -- you get the famous warning saying Jest is still alive 1 second after it should have ended, and can't distinguish this cause for it from a real problem with your tests/code. That is what happens at best, actually, and at worst - your callback is force-killed prematurely along with the worker itself.
@d4vidi that makes sense, thanks for the tip! Are you running without jest's module resetting stuff so that you keep a handle on your per-worker shared resource throughout the run? I have been trying to get the same thing going but struggling to keep any kind of persistent state between suites because of the module reset, which seems desirable for other reasons.
Seems like it would help this person out a lot... also anyone who managed to get here from trying to figure out how to setup a DB per worker - this is a possible inelegant work around. https://github.com/facebook/jest/issues/10552
We already have the means to bring up emulators on a per-worker basis
@d4vidi – I'm curious, how did you implement this?
I am pretty noob js developer but I made something up that *solves** this issue. And please don't critize I just mean to present a solution for curious people by this comment.
*
means solving with my own test runner not with jest runner.
flash
is my test runner I created few days back, to test this you need below setup:
git clone https://github.com/sahilrajput03/flash
cd flash && npm link
cd ..
git clone https://github.com/sahilrajput03/learning-monogo-and-mongoosejs
cd learning-monogo-and-mongoosejs/mongoosejs-with-hot-flash
npm i && npm link flash
npm start
Now if you edit code in code.js
, then you database connection won't be thrown away but reused thus giving you a lightning fast TDD experience with no connection loosing on running tests while in watch mode.
This issue is stale because it has been open for 1 year with no activity. Remove stale label or comment or this will be closed in 30 days.
Not stale.
@SimenB or other maintainers – would a PR implementing this proposal be welcome?
In our testcase we need to share a (non-serializable) ts-morph
Project
between test files, because the typescript API does several seconds of sync parsing whenever we use it.
Having one instance per worker would completely solve the performance problems we face. And it's truly the only way we could get both good performance and file structure; TS API objects aren't serializable and having fully isolated test suites isn't giving us any worthwhile safety guarantees in this case.
This issue is stale because it has been open for 1 year with no activity. Remove stale label or comment or this will be closed in 30 days.
Not stale.
🚀 Feature Proposal
Jest provides once-global setup and teardown, and per-file setup and teardown, but conspicuously absent is per-worker setup and teardown.
Motivation
One worker's set of tests runs serially, and is ideally suited to reusing an exclusive resource like a database or redis connection.
Example
Sue has a test suite that uses a database. She can create multiple databases, but there is a time cost associated with spinning one up before it can be used.
From her test suite she'd like to get maximum concurrency with minimum database setup time.
Currently possible approaches: 1) One database, run all the tests serially.
beforeAll()
)globalSetup
)-w
(or get the wrong number inferred by your CPU core count), and it will either do too much work or not have enough databases.Ideally, instead:
4) Multiple databases, created once per-worker
-w
you want (or let Jest infer it), and you'd get the exact right number of databases.Pitch
I'm not sure where the boundary of core platform is, but it stands to reason that
beforeWorker
andafterWorker
should be provided by the same system that providesbeforeAll
,beforeEach
, andglobalSetup
.Alternatives
I googled around but couldn't come up with another way to achieve this. Is there another (perhaps undocumented) way to hook into worker setup/teardown?