Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Better eunit failure output with unite and `assertEqual`

Problem: an eunit test was using ?assertMatch over a large datastructure and the output was truncated and impossible to debug. The failure was:

**error:{assertMatch_failed,[{module,riak_kv_qry},
                    {line,428},
                    {expression,"Res"},
                    {pattern,"{ ok , { _ , _ , ExpectedRows } }"},
                    {value,{ok,{[<<"Subquery">>,<<"Coverage Plan">>,
                                 <<"Range Scan Start"...>>,
                                 <<"Is Start Inc"...>>,<<"Range Sc"...>>,
                                 <<"Is E"...>>,<<...>>],
                                [sint64,varchar,varchar,boolean,varchar,
                                 boolean|...],
                                [[1,<<"dev1@127"...>>,<<"c = "...>>,false|...],
                                 [2,<<"dev1"…>>,<<...>>|...]]}}}]}

The test code was:

?assertMatch(
    {ok, {_, _, ExpectedRows}},
    Res),

To debug this we enabled the unite formatter in the rebar.config:

{eunit_opts, [no_tty, {report, {unite_compact, []}}]}.

And changed the test so that ?assertEqual could be used, this allows unite to format the failure as a diff between the expected and actual result.

{ok, {_, _, ActualRows}} = Res,
?assertEqual(ExpectedRows, ActualRows),

In the first line, the result is unpacked and just the part we want to run the assertion is bound to a variable. If this results in a badmatch then hopefully the error will be easy to debug, for example {error, _} will not match {ok, {_,_,_,ActualRows}} and it should be easy to compare the difference.

With the ?assertEqual and unite, we get this failure output:

 1) explain_query_test/0 (src/riak_kv_qry.erl:428)
   Assert equal failed! -Expected- +Actual+
   [[1,<<"dev1@127.0.0.1/0, dev1@127.0.0.1/1, dev1@127.0.0.1/1">>,<<"c = 'hola', b = 1">>,false,
     <<"c = 'hola', b = 1000">>,false,-<<"(((d = 15) OR ((e = true) AND (f = 'adios'))) AND (a = 319))">>-+<<"(((d = 15) OR ((e = true) AND (f = <<\"adios\">>))) AND (a = 319))">>+],
    [2,<<"dev1@127.0.0.1/0, dev1@127.0.0.1/1, dev1@127.0.0.1/1">>,<<"c = 'hola', b = 1000">>,false,
     <<"c = 'hola', b = 2000">>,false,-<<"(((d = 15) OR ((e = true) AND (f = 'adios'))) AND (a = 319))">>-+<<"(((d = 15) OR ((e = true) AND (f = <<\"adios\">>))) AND (a = 319))">>+]]

The expected and actual is shown inline, the expected in blue and the actual in yellow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.