Skip to content

Instantly share code, notes, and snippets.

@andytill
Created November 16, 2016 14:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andytill/d067b0bddc98c2bbc8fb2bd421e2ab2c to your computer and use it in GitHub Desktop.
Save andytill/d067b0bddc98c2bbc8fb2bd421e2ab2c to your computer and use it in GitHub Desktop.
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