Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose an id for concurrent test runners (like JEST_WORKER_ID) #55842

Open
blimmer opened this issue Nov 13, 2024 · 7 comments
Open

Expose an id for concurrent test runners (like JEST_WORKER_ID) #55842

blimmer opened this issue Nov 13, 2024 · 7 comments
Labels
feature request Issues that request new features to be added to Node.js. good first issue Issues that are suitable for first-time contributors. test_runner Issues and PRs related to the test runner subsystem.

Comments

@blimmer
Copy link

blimmer commented Nov 13, 2024

What is the problem this feature will solve?

When running tests concurrently (the default setting in the Node test runner), it's common practice to split concurrent test runs across multiple local resources (like locally running servers, databases, etc).

Many other popular test runners offer this feature via an environment variable:

This makes it very easy to set up the proper database connection. For example, here's a snippet from my codebase:

if (process.env.STAGE === "test" && process.env.JEST_WORKER_ID) {
  process.env.DB_DATABASE = `myapp_tests_${process.env.JEST_WORKER_ID}`;
}

Then, in my database docker container, I create n databases, one for each worker. For example, if I run jest with --maxWorkers 8, I create myapp_tests_1 -> myapp_tests_8. During tests, the parallel test suites talk to a different database to avoid deadlocks.

What is the feature you are proposing to solve the problem?

The simplest solution for users coming from other frameworks would be to provide an environment variable just like the other test runners (e.g., NODE_TEST_WORKER_ID).

However, if that's not feasible, adding a workerId to the TestContext could also be a good solution. This solution is not as ideal as the environment variable because people would need to pass the test context to whatever establishes their db/server/etc connection. In my case, at least, this would require refactoring of code. Right now, I rely on that variable being set at file import time.

What alternatives have you considered?

I considered trying to find a solution based on pid, but it's not reliable enough. @RedYetiDev mentioned in Slack that there might be a solution using hooks. I have not dug into this yet.

@blimmer blimmer added the feature request Issues that request new features to be added to Node.js. label Nov 13, 2024
@github-project-automation github-project-automation bot moved this to Awaiting Triage in Node.js feature requests Nov 13, 2024
@RedYetiDev RedYetiDev added the test_runner Issues and PRs related to the test runner subsystem. label Nov 13, 2024
@RedYetiDev RedYetiDev moved this from Awaiting Triage to Triaged in Node.js feature requests Nov 13, 2024
@cjihrig
Copy link
Contributor

cjihrig commented Nov 16, 2024

We could add an environment variable fairly easily, but I have a question:

if (process.env.STAGE === "test" && process.env.JEST_WORKER_ID) {
  process.env.DB_DATABASE = `myapp_tests_${process.env.JEST_WORKER_ID}`;
}

There is already a NODE_TEST_CONTEXT environment variable that can be used to determine that the test runner is being used (if you actually need something like that). Why not use something like crypto.randomUUID() to create a unique ID for each file?

@blimmer
Copy link
Author

blimmer commented Nov 16, 2024

The problem is that, as an external step before the test runner is launched, I:

  • Start up the postgres instance via docker compose
  • Run an init script to create n databases (based on the parallelism I run the tests with)
  • Run my migration logic (node-pg-migrate) against all the test databases
  • Create a flush_database() function in each test database to run beforeEach test

I don't want to do this for each test file because the migration logic is quite slow. It's much faster to migrate once and have a fast flush_database function to reset database state between tests.

So a UUID, for my use case, would not be appropriate. Having a sequential integer between 1 and n (where n is the max concurrency) is required for the database setup logic that occurs outside the test runner context.

@cjihrig
Copy link
Contributor

cjihrig commented Nov 16, 2024

Got it. Thanks for the explanation. I think we should add support for this.

@MoLow MoLow added the good first issue Issues that are suitable for first-time contributors. label Nov 17, 2024
@cu8code
Copy link

cu8code commented Nov 18, 2024

I can work on this! will pick this up!

@cjihrig
Copy link
Contributor

cjihrig commented Nov 18, 2024

Thanks @cu8code. Please be sure to handle both cases of test isolation. When --experimental-test-isolation=process, each child process should get an environment variable from 1 to N. When --experimental-test-isolation=none, only the value of 1 should be used.

@hpatel292-seneca
Copy link

Hi @cu8code, are you working on this? If not I can give it a try.

@cu8code
Copy link

cu8code commented Nov 22, 2024

I am working on this 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request Issues that request new features to be added to Node.js. good first issue Issues that are suitable for first-time contributors. test_runner Issues and PRs related to the test runner subsystem.
Projects
Development

No branches or pull requests

6 participants