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

test_runner: allow to force exit after all tests finished #49925

Closed
rluvaton opened this issue Sep 28, 2023 · 17 comments · Fixed by #52038
Closed

test_runner: allow to force exit after all tests finished #49925

rluvaton opened this issue Sep 28, 2023 · 17 comments · Fixed by #52038
Labels
feature request Issues that request new features to be added to Node.js. test_runner Issues and PRs related to the test runner subsystem.

Comments

@rluvaton
Copy link
Member

What is the problem this feature will solve?

if you have some resource that you don't control blocks the process from exiting (socket/timer/etc) the tests will never finish

having timeout in the run options marking the test as failed

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

allow to specify force exit option that after all tests finished will exit

similar solutions in other frameworks:

What alternatives have you considered?

No response

@rluvaton rluvaton added feature request Issues that request new features to be added to Node.js. test_runner Issues and PRs related to the test runner subsystem. labels Sep 28, 2023
@rluvaton
Copy link
Member Author

cc @nodejs/test_runner

@aduh95
Copy link
Contributor

aduh95 commented Sep 28, 2023

Do we need to do anything? Wouldn't a process.exit() call in after already does what you want?

@cjihrig
Copy link
Contributor

cjihrig commented Sep 28, 2023

I don't quite understand the use case.

if you have some resource that you don't control

It's your test suite, so in theory you have some level of control over all of the resources. It sounds like you just aren't cleaning up after yourself properly.

@MoLow
Copy link
Member

MoLow commented Sep 28, 2023

in node:test there is no such event as "after all tests finished".

this is totally valid:

await setTimeout(10 * 60 * 1000) // sleep for ten minutes
test('run a test after ten minutes', () => {});

and there is no way to know a test is going to be enqueued besides waiting for event loop to drain using process.on('beforeExit') - that is what we do already.

@rluvaton
Copy link
Member Author

rluvaton commented Sep 28, 2023

Do we need to do anything? Wouldn't a process.exit() call in after already does what you want?

process.exit will mess with the reporting as the report will not have enough time to reach the parent process (waiting for a second and then exiting solves this but I don't think it's a solution)

@rluvaton
Copy link
Member Author

I don't quite understand the use case.

if you have some resource that you don't control

It's your test suite, so in theory you have some level of control over all of the resources. It sounds like you just aren't cleaning up after yourself properly.

Unfortunately, the use case is some dependency of dependency that I'm using is not cleaning up...

@atlowChemi
Copy link
Member

Unfortunately, the use case is some dependency of dependency that I'm using is not cleaning up...

@rluvaton that sounds to me like a bug within the dependency, which should be fixed there...

In addition, as Moshe said, the test runner can't tell if all tests completed, as we do not build the test tree before executing the tests, which means adding such an implementation would also make executing the tests that much slower...

@benjamingr
Copy link
Member

I think this is reasonable and test-runners typically implement this because it's common enough, I'm also not sure we can implement this reasonably with our current design.

We can however (with a flag) exit when no more tests are enqueued within a microtick after all already enqueued tests were run which should work well in practice maybe?

@cjihrig
Copy link
Contributor

cjihrig commented Sep 28, 2023

I disagree. I don't think we should implement this, if for no other reason than I don't think it's worth another CLI flag. You're literally saying you have no control over your own application if you can't make it stop.

@MoLow
Copy link
Member

MoLow commented Sep 28, 2023

another option is to add on the TestContext a getter with the pending tests count, this wat on the after/afterEach hook it will be possible to run cleanup code depending on that getter

@cjihrig
Copy link
Contributor

cjihrig commented Sep 28, 2023

I don't mind that idea, but if I understand #49925 (comment) correctly, the problem is that they are not able to perform any cleanup.

(I'm curious to hear more about this by the way because if the issue is that a handle is holding the event loop open, you should be able to use something like process._getActiveHandles() to find it and likely force close it. It's not ideal, but it sounds like neither is the current situation.)

@albanm
Copy link

albanm commented Nov 14, 2023

How about exposing a function that would force the reporter to print its result so that the user can use process.exit() afterward ? Maybe something like "context.report()".

I think the importance of this functionality is understated in this issue. Unfortunately in a nodejs project ensuring that you have a perfectly clean state after running complex tests can be quite difficult and is not always worth the effort (_getActiveHandles was deprecated and getActiveResourcesInfo is not really sufficient). I think that providing an easy way out is important for usability.

@ErickWendel
Copy link
Member

ErickWendel commented Nov 15, 2023

I'm +1 for implementing this.

Another common use case is when Child Processes are being opened and never closed. Another is you'd use e2e tests to spin up a bunch of server instances and don't bother of closing the server on tests as in production would be only a single server instance.

This is very helpful IMHO.

I agree that we'd use getAcive handles and check it out ourselves or the best scenario would be checking manually for handles and closing them. But in my experience, while migrating from one test runner to another having a way to force exit after all tests have been completed would be the best user experience and would prevent some friction on how it works on other frameworks but in the native runner.

We could also show a warning of the active handles while forcing exiting and help users understand what could be the problem (as we have already when we reach the maximum listeners count)

@albanm
Copy link

albanm commented Nov 15, 2023

A socket kept alive by an http agent is another example. Sure I can spend 1 hour tracking it down (like I did just today) and either find a way to change the agent parameters or grab a reference and destroy it in test cleanup. But there is no added value. I don't feel like I get a better control of my program as the change only concerns the test suite, and I am worried that the next time something similar happens I might get stuck for real and be forced to move the whole test suite to another runner.

@walterlarrea
Copy link

I'm trying to use Test Runner as testing tool for an express api and this prevents my pipeline from completing tests and continue with further steps. Am I missing something? Isn't this a good enough use case?

@KunalBurangi
Copy link

I also have the same issue
all the tests are successful but it seems like the runner is stuck...
I think an option like --exit similar to mocha would make node: test more usable.

cjihrig added a commit to cjihrig/node that referenced this issue Mar 10, 2024
This commit updates the test runner to allow a forced exit once
all known tests have finished running.

Fixes: nodejs#49925
cjihrig added a commit to cjihrig/node that referenced this issue Mar 10, 2024
This commit updates the test runner to allow a forced exit once
all known tests have finished running.

Fixes: nodejs#49925
@cjihrig
Copy link
Contributor

cjihrig commented Mar 10, 2024

#52038

cjihrig added a commit to cjihrig/node that referenced this issue Mar 11, 2024
This commit updates the test runner to allow a forced exit once
all known tests have finished running.

Fixes: nodejs#49925
nodejs-github-bot pushed a commit that referenced this issue Mar 13, 2024
This commit updates the test runner to allow a forced exit once
all known tests have finished running.

Fixes: #49925
PR-URL: #52038
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
Reviewed-By: Raz Luvaton <rluvaton@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
rdw-msft pushed a commit to rdw-msft/node that referenced this issue Mar 26, 2024
This commit updates the test runner to allow a forced exit once
all known tests have finished running.

Fixes: nodejs#49925
PR-URL: nodejs#52038
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
Reviewed-By: Raz Luvaton <rluvaton@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
marco-ippolito pushed a commit that referenced this issue May 2, 2024
This commit updates the test runner to allow a forced exit once
all known tests have finished running.

Fixes: #49925
PR-URL: #52038
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
Reviewed-By: Raz Luvaton <rluvaton@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
jcbhmr pushed a commit to jcbhmr/node that referenced this issue May 15, 2024
This commit updates the test runner to allow a forced exit once
all known tests have finished running.

Fixes: nodejs#49925
PR-URL: nodejs#52038
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
Reviewed-By: Raz Luvaton <rluvaton@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
marco-ippolito pushed a commit that referenced this issue May 23, 2024
This commit updates the test runner to allow a forced exit once
all known tests have finished running.

Fixes: #49925
PR-URL: #52038
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
Reviewed-By: Raz Luvaton <rluvaton@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Cruikshanks added a commit to DEFRA/water-abstraction-node-test that referenced this issue Oct 8, 2024
Now we've imported and updated all our models it is time to start adding some example tests to drive research of node-test as an alternate to Lab further.

In database terms, all models are accessed and used in the same way via Objection.js. However, we split them into two camps for testing; reference models and transaction models.

Reference models are things we don't expect to be creating within the service as part of daily use. They are records that would be seeded, for example, regions.

Transaction models are things we expect to be created, for example, bill runs or licences.

When it comes to testing we seed the tables that back the reference models, hence their helpers generally have a `select()` method. Transaction models, when needed, will be created during the testing. Their helpers generally have an `add()` method.

When we first tried this test, node-test wouldn't quit. It wouldn't even move to the next spec after `region.model.test.js`. This is a problem we first faced when pulling this project together. Time away has clearly helped because we were able to diagnose the cause as the database connection we create blocks node test from exiting (see [test_runner: allow to force exit after all tests finished](nodejs/node#49925) for a deeper dive into the issue which gave us our a-ha! moment).

It does mean we'll need to add an `after()` block into any spec that results in a DB connection being made. But that should be simple enough.

Completing this example has also highlighted that we'll probably want to extend `assert` in some way, to avoid 'messy duplication' in our tests.

But for now, here is our first working model node-test!
Cruikshanks added a commit to DEFRA/water-abstraction-node-test that referenced this issue Oct 8, 2024
Now that we've imported and updated all our models, it is time to start adding some example tests to further research node-test as an alternative to Lab.

In database terms, all models are accessed and used via Objection.js. However, for testing, we split them into two camps: reference models and transaction models.

Reference models are things we don't expect to create within the service as part of daily use. They are records that would be seeded, such as regions.

Transaction models are things we expect to be created, such as bill runs or licences.

When it comes to testing we seed the tables that back the reference models, hence their helpers generally have a `select()` method. Transaction models, when needed, will be created during the testing. Their helpers generally have an `add()` method.

When we first tried this test, node-test wouldn't quit. It wouldn't even move to the next spec after `region.model.test.js`. This is a problem we first faced when pulling this project together. Time away has clearly helped because we were able to diagnose the cause as the database connection we create blocks node test from exiting (see [test_runner: allow to force exit after all tests finished](nodejs/node#49925) for a deeper dive into the issue which gave us our a-ha! moment).

This does mean we'll need to add an `after()` block to any spec that results in a DB connection being made, but that should be simple enough.

Completing this example has also highlighted that we'll probably want to extend `assert` in some way, to avoid 'messy duplication' in our tests.

But for now, here is our first working model node-test!
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. test_runner Issues and PRs related to the test runner subsystem.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants