-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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
Planned assertion count / Hook into timeout? (for testing runtime) #44125
Comments
Just to add a more real world example if it helps. In the below example, the test will wait if test('test 2 assertions will timeout', { timeout: 2000 }, async t => {
const assert = assertPlan(1);
chatbot.addEventListener('message', (message) => {
assert.strictEqual(message.content, 'hello world');
})
await assert.wait();
}); But all you'll get in the logs are:
But really, it would be helpful for me to somehow say:
|
I guess a solution could be the ensure we never use the test runners timeout, and rely soley on It feels wrong to me, but I think I'd be easily convinced otherwise. |
Thanks for the detailed issue. Just a few observations:
|
We expose the AbortSignal in the test which has the event you describe and you can use. On the other hand I do see value in exposing common.mustCall/common.mustNotCall we use extensively in our own tests maybe? |
that is already possible - just combinie |
also, implementing a plan for testing (any plan, not just for assersions) can be done with a counter and checking it inside a |
can this issue be closed? |
Thank you everyone for taking the time to help me and come up with so many ideas/suggestions. I really appreciate it. The before/after hook seems like a great way to solve this. I'll try it once it get's published. |
Hi folks, apologies for resurrecting an old issue but we find ourselves needing the assestion planning feature that exists in most testing framework such as tap and jest, and which is hard to replicate without native support from the test runner. Here's a simple example of something you'd write in tap: test('plan', t => {
t.plan(1)
doSomething(() => t.ok(true))
}) Rewriting this test without native support for assertion planing is tricky. One way would be to create a promise: test('no plan', t => {
let resolve
const p = new Promise(_resolve => { resolve = _resolve })
doSomething(() => {
t.ok(true)
resolve()
})
return p
}) Clearly, this gets complicated and unfeasible very quickly, e.g. imagine nested callbacks, and has no easy user-space solution. As much as I dislike test planning, because it makes tests harded to write and change, it's the only sensible way that I'm aware of to support assertions in callbacks, which are in some cases unavoidable. Thoughts? |
I have a branch implementing this exact thing, but was on the fence as to whether or not to PR it. It would be good to hear what others think since a fair amount of time has passed since this issue was originally opened. |
That's a good start and good to hear, thanks @cjihrig. I assume that this also includes wrapping the assert module so it plays well along with node:test, right? Personally, I'd say that 90% of the test I come across don't need this, but when you do, not having this feature is a show stopper. |
That's correct. Here is some code from my branch: test('plan passes with callbacks', (t, done) => {
t.plan(3);
t.assert.ok(true);
setImmediate(() => {
t.assert.ok(true);
done();
});
t.assert.ok(true);
}); And, I haven't implemented it yet, but I designed this such that in the future we could support:
|
That's the way I would imagine it would look like. Now if it also worked, it would be amazing ;) |
@simoneb have a look at https://github.com/mcollina/tspl |
Thanks, I wasn't aware that Matteo built one. I'm sure there are alternatives, it would be great to pick one and bundle it in node:test. |
This is all it really takes to build it in: cjihrig@89d9a7e. Unlike a userland solution, this can also be easily extended to address #52033 (silent node-tap style assertions). |
The fundamental reason I needed tspl was supporting Node 18 too. |
What is the problem this feature will solve?
When writing tests, I really like the
plan
function in tape.In summary it lets you specify how many assertions you expect to have, then the test will fail if there are fewer/more than planned.
I'm really loving the new built in testing runtime, but I'm really missing
plan
. So I've built a wrapper around assert that implements the plan function in a similar way.https://github.com/markwylde/assert-plan#example-usage
It's working really well, but there's a problem when the test timesout. I would like to log out the test timed out due to not receiving enough planned assertions.
To get around this I have to provide two timeouts, as below: (it works, but it's not very nice):
For example
Notes:
assertPlan
times out, it throws and error that is outputted to the user.What is the feature you are proposing to solve the problem?
I think there's probably an obvious existing solution, or I'm trying to solve something in a strange way. So I'm really open to criticism on my approach. But some ideas off the top of my head are:
Proposal 1 - expose the timeout on
t
Proposal 2 - expose an event when a test timesout
Proposal 3 - test timeout hook
What alternatives have you considered?
I originally thought if we could add a
plan
function to the test runtime, liketape
does:For example:
But it breaks the cleanest of the
test
module, and how it's not coupled withassert
at all. So I feel the right solution is to wrap/use an alternative assert library.Maybe we could add a
plan
to theassert
module, but you could be running multiple tests in parallel andassert
wouldn't have a way of accumulating counts for just the specific test you are running.You could make
assert
a constructor, but even then the problem of how to timeout the wait when the test timeouts still exists.Thank you for humoring my idea and sorry if there is some really obvious stuff I'm missing here.
The text was updated successfully, but these errors were encountered: