One way to do this is use rebar3
to run a shell under the test profile, then start the debugger and set up your breakpoints and such:
$ rebar3 as test shell
...
1> debugger:start().
{ok, <0.67.0>}
This will pop up the debugger GUI. Once the debugger is set up and ready, run your test under eunit
:
2> eunit:test(your_test_module,[verbose]).
======================== EUnit ========================
your_test_module: xyz_test_ (module 'your_test_module')...
Assuming you set up a suitable breakpoint in the debugger, this will hit it, but you'll likely run into a problem with this approach: by default, eunit
tests time out after 5 seconds, which doesn't give you much time for debugging. You need to specify a longer timeout for your test, which is why the example above shows that what's running is a test fixture named xyz_test_
, which wraps the actual test with a long timeout. Such a fixture is pretty simple:
-include_lib("eunit/include/eunit.hrl").
xyz_test_() ->
{timeout,3600,
[fun() -> ?assertMatch(expected_value, my_module:my_fun()), ok end]}.
Here, the actual test is the anonymous function, which matches the return value from my_module:my_fun/0
, which for this example represents the business logic under test. This example fixture sets the test timeout to one hour; you can of course set it as needed for your application.
-noshell
flag when it runs eunit tests, so you can't attach to Erlang console to debug your code when rebar is running. Calling eunit tests are as easy as a function call, so you can call them from Erlang console when your application is started by./your-app-release console
or./your-app-release remote_shell
commands. – Edaedacious