I am currently writing a test suite using busted/luassert and since I have put some assertions in a separate function I am getting inaccurate stack traces. For example, consider the following test suite (a_spec.lua):
local function my_custom_assertion(x) -- 1
assert.is_true(x > 0) -- 2 <-
end -- 3
-- 4
describe("My test suite", function() -- 5
it("they are positive", function() -- 6
my_custom_assertion(-10) -- 7 <-
my_custom_assertion(-20) -- 8 <-
end) -- 9
end) -- 10
When I run it, my test case fails but the stack trace points to line 2 so I can't tell which of the two assertions was the one that failed.
$busted spec/a_spec.lua
◼
0 successes / 1 failure / 0 errors / 0 pending : 0.002242 seconds
Failure → spec/a_spec.lua @ 6
My test suite they are positive
spec/a_spec.lua:2: Expected objects to be the same.
Passed in:
(boolean) false
Expected:
(boolean) true
Is there a way I could have it point to line 7 or 8 instead? One way this would be possible is if luassert's assert.is_true function had a level parameter similar to the builtin error function.
Looking at luassert's source code it seems that it does care about the stack level but I haven't been able to figure out if this feature is internal or if it is exposed to the user somehow.
Turns out that there is a way to solve my actual problem of finding out which of the assertions was the one that fired without needing to change how I write my tests. By invoking busted
with the -v
(--verbose
) option it prints a full stack trace when an assertion fails instead of just providing a single line number.
$ busted -v spec/a_spec.lua
0 successes / 1 failure / 0 errors / 0 pending : 0.003241 seconds
Failure → spec/a_spec.lua @ 6
My test suite they are positive
spec/a_spec.lua:2: Expected objects to be the same.
Passed in:
(boolean) false
Expected:
(boolean) true
stack traceback:
spec/a_spec.lua:2: in upvalue 'my_custom_assertion'
spec/a_spec.lua:7: in function <spec/a_spec.lua:6>
That mention of line number 7 lets me know what assertion was the one that failed.