EUnit and code loading

Lars <>
Mon Sep 27 17:08:05 CEST 2010


Hi!

I have a problem with EUnit and loading code in runtime that I believe to be
a bug. Consider these two simple modules a and b that I made to illustrate
the problem:

Module a:
-module(a).
-include_lib("eunit/include/eunit.hrl").

a_test() ->
load_new_b(),
new = b:f().

load_new_b() ->
code:purge(b),
code:delete(b),
{ok, Module, Binary} = compile:forms([{attribute, 1, module, b},
  {attribute, 1, export, [{f, 0}]},
  {function, 1, f, 0, [{clause, 1, [], [], [{atom, 1, new}]}]}]),
{module, b} = erlang:load_module(b, Binary).


Module b:
-module(b).
-include_lib("eunit/include/eunit.hrl").
-export([f/0]).

f() ->
old.


load_new_b replaces the b module and changes the definition of b:f to return
the atom new instead of old, so a_test should pass.

To reproduce the problem:
* Compile a.erl and b.erl and start a shell
* Run eunit:test("a.beam").
* Run eunit:test("b.beam").
* Run eunit:test("a.beam").

The output will be on the form:

1> eunit:test("a.beam").
  Test passed.
ok
2> eunit:test("b.beam").
  There were no tests to run.
ok
3> eunit:test("a.beam").
a: a_test (module 'a')...*failed*
::error:{badmatch,old}
  in function a:a_test/0
  in call from eunit:test/1


However, if instead of the "a.beam" syntax the modules are named as terms
(eunit:test(a)), the above works.
Both eunit:test({inorder, [b, a]}) and eunit:test({inorder, ["b.beam",
"a.beam"]}) fail.

So the problem is that I can't replace a module that has been previously
tested by EUnit. For some reason it works when using the module term syntax,
though.

Verified on Mac OS X 10.6.4, Erlang version: R14B. Probably Linux also,
although this exact program was not tested there. Does not seem to occur in
Windows.

/ Lars


More information about the erlang-bugs mailing list