7

I have a medium-sized release with a handful of applications. I recently refactored some common functionality out into a library application within the release. This made my EUnit tests fail with undef messages whenever testing anything that required the library application.

The set up is something like this:

% In apps/utils/src/utils.erl
-module(utils).

-export([foo/0]).

foo() -> "OH HAI".

Then

% In apps/some_app/src/some_app.erl
-module(some_app).

-export([bar/0]).

bar() -> io:format("foo: ~s~n", [utils:foo()]).

% unit tests for bar()

Then the unit tests for some_app:bar() fail. I'm running them with rebar eunit skip_deps=true. I'm using skip_deps=true because my release uses some 3rd party applications (SQL, etc).

I assume that the tests start failing because EUnit is invoking the app under test without its dependencies? Is there any way to fix this? I have configured the .app file to explicitly declare the dependency. It works fine in the release, and it's been deployed for about a day now with no problem, but I'll feel a lot better if I can get the tests to pass again :)

(I could use a mocking app to stub out utils:foo/0, and I can see where that would be ideal idiomatically, but that seems like overkill in this case because utils:foo/0 (read: it's real-world counterpart) does some really simple stuff.)

dantswain
  • 5,427
  • 1
  • 29
  • 37
  • I think this has nothing to do with EUnit itself, but how Rebar is running the tests. Either because it simply doesn't compile the other applications when you use skip_deps, or because it doesn't add them to the Erlang code path even if they have been compiled previously. – RichardC Nov 09 '12 at 20:27
  • I think I need to dig into the rebar source to figure this one out :/ I *think* the `skip_deps` flag just skips the unit tests in the `deps` directory (which is being used for 3rd-party stuff). – dantswain Nov 10 '12 at 16:20
  • As far as I can tell from looking at the rebar source, `skip_deps` just tells rebar to skip applications in the `deps` directory. – dantswain Nov 12 '12 at 15:28

2 Answers2

2

I was able to get this to work by doing rebar compile eunit skip_deps=true.

The key is to have the compile in there and I have no idea why. I'm guessing that the compile step gets all of the modules into memory. I'd love to hear a good explanation.

dantswain
  • 5,427
  • 1
  • 29
  • 37
0

I think you could have one of your applications load the utility by including it in the application portion of you .app file, as in:

{application,yourapp
         [{description,"A description"},
          {vsn,"1.0.0"},
          {modules,[mod1, mod2, utils]},
           SNIP

or in some other way add it to the path of the erlang node... maybe using the -pa flag on starting the node.

Jr0
  • 2,131
  • 13
  • 23
  • 1
    The module is part of another application. It is listed as a dependency in the `applications` section of the .app file. The `modules` section is for modules introduced by that app, so not appropriate. I tried it anyways, though, and it still didn't work. – dantswain Nov 12 '12 at 15:26