You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Asserting a range with descriptive error messages #4461
I work a lot with performance testing code which frequently leads in the unfortunate position where I need to assert ranges rather than exact values, i.e
is value between 1500 and 2000?
Now, to do that I use a pair of assert.ok like so:
importtestfrom'node:test'awaittest('is within range',asynct=>{constvalue=2700t.assert.ok(value>=1500)t.assert.ok(value<=2000)})
✖ is within range (1.220792ms)
AssertionError [ERR_ASSERTION]: false == true
at assert.<computed> [as ok] (node:internal/test_runner/test:261:18)
at TestContext.<anonymous> (file:///Users/nicholaswmin/Projects/fsm/scratch.js:7:12)
at Test.runInAsyncScope (node:async_hooks:211:14)
at Test.run (node:internal/test_runner/test:878:25)
at Test.processPendingSubtests (node:internal/test_runner/test:590:18)
at node:internal/test_runner/harness:252:20
at node:internal/process/task_queues:151:7
at AsyncResource.runInAsyncScope (node:async_hooks:211:14)
at AsyncResource.runMicrotask (node:internal/process/task_queues:148:8) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: false,
expected: true,
operator: '=='
}
My "complaint" is that it doesn't print value being asserted against, unless I specifically code it to so with that string interpolation.
Now granted, the above is impossible to do with the code I'm providing because that's a Boolean expression.
An ideal API might be something like:
I'm personally against adding specific assertion checks to assert like that.
It'll eventually snowball into a myriad utilities. I miss the hyper-declarative syntax of Chai but I've also come to love the minimal, no-frills API surface of assert since I don't need to memorise a million method names.
... I don't remember what i had in mind when i opened this.
If I need range checks I can extend assert locally.
✖ is in range (1.220875ms)
AssertionError [ERR_ASSERTION]: `value >= 1500`
at assert.<computed> [as ok] (node:internal/test_runner/test:261:18)
at TestContext.<anonymous> (file:///Users/nicholaswmin/Projects/fsm/scratch.js:7:12)
at Test.runInAsyncScope (node:async_hooks:211:14)
at Test.run (node:internal/test_runner/test:878:25)
at Test.processPendingSubtests (node:internal/test_runner/test:590:18)
at node:internal/test_runner/harness:252:20
at node:internal/process/task_queues:151:7
at AsyncResource.runInAsyncScope (node:async_hooks:211:14)
at AsyncResource.runMicrotask (node:internal/process/task_queues:148:8) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: false,
expected: true,
operator: '=='
}
which is more descriptive than the current:
AssertionError [ERR_ASSERTION]: false == true
Not sure if that's doable without doing esprima-like parsing though?
Activity
avivkeller commentedon Aug 4, 2024
CC @nodejs/assert
gireeshpunathil commentedon Sep 4, 2024
looks reasonable to me!
gireeshpunathil commentedon Sep 4, 2024
@nicholaswmin - pls feel free to raise a PR if you are willing to!
avivkeller commentedon Sep 4, 2024
Although, doesn't the assert message include the failed assertion line, so wouldn't it already show the failure?
nicholaswmin commentedon Sep 4, 2024
@redyetidev here's the output:
My "complaint" is that it doesn't print
valuebeing asserted against, unless I specifically code it to so with that string interpolation.Now granted, the above is impossible to do with the code I'm providing because that's a Boolean expression.
An ideal API might be something like:
AssertionError [ERR_ASSERTION]: Failed, value: 2700 was not ok
Hmm.. I'm a bit confused... Not sure why I opened this issue as what I'm proposing sounds like a silly API.
Doing this:
prints the value anyway.
I don't remember what I had in mind. Sorry.
avivkeller commentedon Sep 4, 2024
assert.isGreaterThan(and vise versa) could work if you'd like to add it?nicholaswmin commentedon Sep 4, 2024
I'm personally against adding specific assertion checks to
assertlike that.It'll eventually snowball into a myriad utilities. I miss the hyper-declarative syntax of Chai but I've also come to love the minimal, no-frills API surface of
assertsince I don't need to memorise a million method names.... I don't remember what i had in mind when i opened this.
If I need range checks I can extend
assertlocally.I think this needs to be closed ??
nicholaswmin commentedon Sep 4, 2024
The closest thing I can figure out that would help without adding specific assertion checks is printing the expression itself on
assert.ok().An example:
logs:
which is more descriptive than the current:
Not sure if that's doable without doing esprima-like parsing though?
avivkeller commentedon Sep 4, 2024
For your specific case, a custom error (E.G.
throw new assert.AssertionError({actual: 1, expected:2, operator:">="})) can be thrown.In some cases, that is what happens:
nicholaswmin commentedon Sep 4, 2024
Yes. That works! That's more than enough.
I can repro your working example with
assertbut not witht.assertavivkeller commentedon Sep 4, 2024
I'm aware. I'm opening an issue for it as we speak.
4 remaining items
avivkeller commentedon Sep 4, 2024
Fixed in nodejs/node#54776
nicholaswmin commentedon Sep 4, 2024
Amazing;
sorry, life got in the way ...
test_runner: reimplement `assert.ok` to allow stack parsing
test_runner: reimplement `assert.ok` to allow stack parsing
test_runner: reimplement `assert.ok` to allow stack parsing
test_runner: reimplement `assert.ok` to allow stack parsing
test_runner: reimplement `assert.ok` to allow stack parsing
gireeshpunathil commentedon Nov 13, 2024
@nicholaswmin - is your proposal addressed? can this be closed now as resolved?