1

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.

hugomg
  • 68,213
  • 24
  • 160
  • 246

2 Answers2

1

Instead of creating a custom assertion by creating a function that calls assert.xyzz(), create a function that returns true or false and register it with assert:register.

See the second example in the README.

basicer
  • 308
  • 2
  • 5
  • The custom assert function that I am actually using is calling `assert.are.same`, which shows a very helpful printout of the mismatched tables if there is an error. Is there a way to still get that if I define my own custom assert function? – hugomg Dec 01 '17 at 00:12
  • util.deepcompare from require ('luassert.util') does most of the hard work there. See https://github.com/Olivine-Labs/luassert/blob/9fecb18f5d31e70d28c252e24fae373687f860d7/src/assertions.lua#L123 – basicer Dec 01 '17 at 01:19
0

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.

hugomg
  • 68,213
  • 24
  • 160
  • 246