7

I'm write a test with EUnit, but not anything exception detail output in console.

exp_test() ->
  ?assertEqual(0, 1/0).

Run this module:exp_test() in the Erlang Shell output following

** exception error: bad argument in an arithmetic expression
 in function  exp_test:'-exp_test/0-fun-0-'/1 (src/test/eunit/xxx_test.erl, line 8)

But in EUnit output following

> eunit:test(xxx).
> xxx_test: exp_test...*failed*
  ::badarith

EUnit not output anything exception trace info

Im trying the verbose config in eunit, but no effect.

I want to output some exception detail in eunit test result.

Thanks~

hpyhacking
  • 285
  • 3
  • 14

4 Answers4

7

The problem seems to be that the version of eunit shipped with R15 does not understand the new stack trace format in R15. This has been fixed in the development version of eunit: github.com/richcarl/eunit

For example:

Eshell V5.10 (abort with ^G)
1> eunit:test(fun() -> (fun() -> exit(foo), ok end)() end).
erl_eval: expr...*failed*
in function erl_eval:do_apply/6 (erl_eval.erl, line 576)
in call from erl_eval:exprs/5 (erl_eval.erl, line 118)
**exit:foo

I hope this will make it into the next release of OTP R15.

RichardC
  • 10,412
  • 1
  • 23
  • 24
  • A [slightly different patch](https://github.com/erlang/otp/commit/73b94a990bb91fd263dace4ccbaef6ff727a9637) made in into `pu` (i.e. meant for the next R15 release) in November 2011. However, it was not included in R15B01 ([released 2012-04-02](http://www.erlang.org/download/otp_src_R15B01.readme)). – legoscia Jun 22 '12 at 12:51
7

This is a known problem in eunit as released in R15B and R15B01. This has been fixed in release R15B02. If you're stuck with an earlier version, you can download and apply a patch:

A workaround for releases before R15B02

You can fix the problem in your local installation by recompiling the affected module:

  1. Download and unpack the Erlang/OTP sources, if you don't have them already.

    wget http://www.erlang.org/download/otp_src_R15B01.tar.gz
    tar xzf otp_src_R15B01.tar.gz
    cd otp_src_R15B01
    
  2. Download and apply the patch.

    wget -O eunit-stacktrace.patch https://github.com/erlang/otp/commit/73b94a990bb91fd263dace4ccbaef6ff727a9637.patch
    patch -p1 < eunit-stacktrace.patch
    
  3. Recompile eunit_lib.erl.

    cd lib/eunit
    erlc -o ebin -I include src/eunit_lib.erl
    
  4. Copy the new eunit_lib.beam over the old one (usually somewhere below /usr/local).

    ls /usr/local/lib/erlang/lib/eunit-2.2.2/ebin/
    # check that eunit_lib.beam is actually there
    sudo cp ebin/eunit_lib.beam /usr/local/lib/erlang/lib/eunit-2.2.2/ebin/
    
legoscia
  • 39,593
  • 22
  • 116
  • 167
4

Eunit is quite old and while it is officially maintained by the OTP team at Ericsson, it is usually uncared for. Eunit currently has the bad habit of eating up stack traces, and hasn't been updated for R15's line numbers in exceptions.

I wouldn't argue that "that's how it's supposed to work". No sane test tool should hide exception details and line numbers for you.

Adam Lindberg
  • 16,447
  • 6
  • 65
  • 85
  • OTP do not maintain EUnit - I do, when I have the time. And help is always welcome. By the way, if you have some example of when EUnit eats a stack trace that it shouldn't, please send it to me. – RichardC May 10 '12 at 09:46
  • What about the above case? It's impossible to deduce wether the exception comes from the test case or the code under test. – Adam Lindberg May 10 '12 at 12:40
  • In his example, the code under test is the test case. ?assertEqual(0, 1/0) is all there is. If the exception had happened deeper down in some called function, you should see a stack trace. But I'll take a closer look at this to see if something more can be done. – RichardC May 10 '12 at 13:35
  • In the morning, I'm try again, write some code in [Gist](https://gist.github.com/2662663), and get same error result. I put the error code in function call not in assert marco. Thank you, RichardC and Adam. You know, find error code in a big module is maddening. – hpyhacking May 11 '12 at 22:03
2

A trick I like to use is ?debugVal(catch expr) where expr is either a begin end block or a call to the failing function. For example, ?debugVal(catch begin 1 = 2 end) will output a stacktrace in your tests.

rramsden
  • 123
  • 2
  • 7
  • @hpyhacking I would highly recommend just cloning down the latest eunit repo and replacing eunit-2.2.2 on your local machine with eunit-2.2.3 for the time being. – rramsden Sep 15 '12 at 02:47