summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/rebar.erl17
-rw-r--r--src/rebar_eunit.erl133
-rw-r--r--test/rebar_eunit_tests.erl2
3 files changed, 95 insertions, 57 deletions
diff --git a/src/rebar.erl b/src/rebar.erl
index 32c95d2..5d9475d 100644
--- a/src/rebar.erl
+++ b/src/rebar.erl
@@ -297,13 +297,16 @@ generate-upgrade previous_release=path Build an upgrade package
generate-appups previous_release=path Generate appup files
-eunit [suites=foo] Run eunit tests [foo.erl and test/foo_tests.erl]
- [suites=foo] [tests=bar] Run specific eunit tests [first test name starting
- with 'bar' in foo.erl and test/foo_tests.erl]
- [tests=bar] For every existing suite, run the first test whose
- name starts with bar and, if no such test exists,
- run the test whose name starts with bar in
- the suite's _tests module
+eunit [suites=foo] Run eunit tests in foo.erl and
+ test/foo_tests.erl
+ [suites=foo] [tests=bar] Run specific eunit tests [first test name
+ starting with 'bar' in foo.erl and
+ test/foo_tests.erl]
+ [tests=bar] For every existing suite, run the first
+ test whose name starts with bar and, if
+ no such test exists, run the test whose
+ name starts with bar in the suite's
+ _tests module
ct [suites=] [case=] Run common_test suites
diff --git a/src/rebar_eunit.erl b/src/rebar_eunit.erl
index 06f0c60..9e6d5e4 100644
--- a/src/rebar_eunit.erl
+++ b/src/rebar_eunit.erl
@@ -119,7 +119,7 @@ run_eunit(Config, CodePath, SrcErls) ->
AllModules = [rebar_utils:beam_to_mod(?EUNIT_DIR, N) || N <- AllBeamFiles],
{SuitesProvided, FilteredModules} = filter_suites(Config, AllModules),
- %% build the tests
+ %% Get matching tests
Tests = get_tests(Config, SuitesProvided, ModuleBeamFiles, FilteredModules),
SrcModules = [rebar_utils:erl_to_mod(M) || M <- SrcErls],
@@ -169,6 +169,10 @@ setup_code_path() ->
true = code:add_pathz(rebar_utils:ebin_dir()),
CodePath.
+%%
+%% == filter suites ==
+%%
+
filter_suites(Config, Modules) ->
RawSuites = rebar_config:get_global(Config, suites, ""),
SuitesProvided = RawSuites =/= "",
@@ -180,65 +184,59 @@ filter_suites1(Modules, []) ->
filter_suites1(Modules, Suites) ->
[M || M <- Modules, lists:member(M, Suites)].
+%%
+%% == get matching tests ==
+%%
get_tests(Config, SuitesProvided, ModuleBeamFiles, FilteredModules) ->
Modules = case SuitesProvided of
- false ->
- %% No specific suites have been provided, use ModuleBeamFiles
- %% which filters out "*_tests" modules so eunit won't doubly run
- %% them and cover only calculates coverage on production code.
- %% However, keep "*_tests" modules that are not automatically
- %% included by eunit.
- %%
- %% From 'Primitives' in the EUnit User's Guide
- %% http://www.erlang.org/doc/apps/eunit/chapter.html
- %% "In addition, EUnit will also look for another module whose
- %% name is ModuleName plus the suffix _tests, and if it exists,
- %% all the tests from that module will also be added. (If
- %% ModuleName already contains the suffix _tests, this is not
- %% done.) E.g., the specification {module, mymodule} will run all
- %% tests in the modules mymodule and mymodule_tests. Typically,
- %% the _tests module should only contain test cases that use the
- %% public interface of the main module (and no other code)."
- [rebar_utils:beam_to_mod(?EUNIT_DIR, N) || N <- ModuleBeamFiles];
- true ->
- %% Specific suites have been provided, return the filtered modules
- FilteredModules
- end,
- build_tests(Config, Modules).
+ false ->
+ %% No specific suites have been provided, use
+ %% ModuleBeamFiles which filters out "*_tests" modules
+ %% so eunit won't doubly run them and cover only
+ %% calculates coverage on production code. However,
+ %% keep "*_tests" modules that are not automatically
+ %% included by eunit.
+ %%
+ %% From 'Primitives' in the EUnit User's Guide
+ %% http://www.erlang.org/doc/apps/eunit/chapter.html
+ %% "In addition, EUnit will also look for another
+ %% module whose name is ModuleName plus the suffix
+ %% _tests, and if it exists, all the tests from that
+ %% module will also be added. (If ModuleName already
+ %% contains the suffix _tests, this is not done.) E.g.,
+ %% the specification {module, mymodule} will run all
+ %% tests in the modules mymodule and mymodule_tests.
+ %% Typically, the _tests module should only contain
+ %% test cases that use the public interface of the main
+ %% module (and no other code)."
+ [rebar_utils:beam_to_mod(?EUNIT_DIR, N) ||
+ N <- ModuleBeamFiles];
+ true ->
+ %% Specific suites have been provided, return the
+ %% filtered modules
+ FilteredModules
+ end,
+ get_matching_tests(Config, Modules).
-build_tests(Config, Modules) ->
+get_matching_tests(Config, Modules) ->
RawFunctions = rebar_utils:get_experimental_global(Config, tests, ""),
Tests = [list_to_atom(F1) || F1 <- string:tokens(RawFunctions, ",")],
case Tests of
[] ->
Modules;
Functions ->
- case build_tests1(Modules, Functions, []) of
+ case get_matching_tests1(Modules, Functions, []) of
[] ->
[];
RawTests ->
- ?CONSOLE(" Running test function(s):~n", []),
- F = fun({M, F2}, Acc) ->
- ?CONSOLE(" ~p:~p/0~n", [M, F2]),
- FNameStr = atom_to_list(F2),
- NewFunction = case re:run(FNameStr, "_test_") =/= nomatch of
- true ->
- %% Generator
- {generator, eunit_test:function_wrapper(M, F2)};
- _ ->
- %% Normal test
- eunit_test:function_wrapper(M, F2)
- end,
- [NewFunction|Acc]
- end,
- lists:foldl(F, [], RawTests)
+ make_test_wrappers(RawTests)
end
end.
-build_tests1([], _Functions, TestFunctions) ->
+get_matching_tests1([], _Functions, TestFunctions) ->
TestFunctions;
-build_tests1([Module|TModules], Functions, TestFunctions) ->
+get_matching_tests1([Module|TModules], Functions, TestFunctions) ->
%% Get module exports
ModuleStr = atom_to_list(Module),
ModuleExports = get_beam_test_exports(ModuleStr),
@@ -246,11 +244,12 @@ build_tests1([Module|TModules], Functions, TestFunctions) ->
TestModuleStr = string:concat(ModuleStr, "_tests"),
TestModuleExports = get_beam_test_exports(TestModuleStr),
%% Build tests {M, F} list
- Tests = build_tests2(Functions, {Module, ModuleExports},
+ Tests = get_matching_tests2(Functions, {Module, ModuleExports},
{list_to_atom(TestModuleStr), TestModuleExports}),
- build_tests1(TModules, Functions, lists:merge([TestFunctions, Tests])).
+ get_matching_tests1(TModules, Functions,
+ lists:merge([TestFunctions, Tests])).
-build_tests2(Functions, {Mod, ModExports}, {TestMod, TestModExports}) ->
+get_matching_tests2(Functions, {Mod, ModExports}, {TestMod, TestModExports}) ->
%% Look for matching functions into ModExports
ModExportsStr = [atom_to_list(E1) || E1 <- ModExports],
TestModExportsStr = [atom_to_list(E2) || E2 <- TestModExports],
@@ -308,6 +307,34 @@ get_beam_test_exports(ModuleStr) ->
[]
end.
+make_test_wrappers(RawTests) ->
+ ?CONSOLE(" Running test function(s):~n", []),
+ F = fun({M, F2}, Acc) ->
+ ?CONSOLE(" ~p:~p/0~n", [M, F2]),
+ FNameStr = atom_to_list(F2),
+ NewFunction =
+ case re:run(FNameStr, "_test_") of
+ nomatch ->
+ %% Normal test
+ eunit_test(M, F2);
+ _ ->
+ %% Generator
+ eunit_generator(M, F2)
+ end,
+ [NewFunction|Acc]
+ end,
+ lists:foldl(F, [], RawTests).
+
+eunit_test(M, F) ->
+ eunit_test:function_wrapper(M, F).
+
+eunit_generator(M, F) ->
+ {generator, eunit_test:function_wrapper(M, F)}.
+
+%%
+%% == run tests ==
+%%
+
perform_eunit(Config, Tests) ->
EunitOpts = get_eunit_opts(Config),
@@ -334,6 +361,10 @@ get_eunit_opts(Config) ->
BaseOpts ++ rebar_config:get_list(Config, eunit_opts, []).
+%%
+%% == code coverage ==
+%%
+
perform_cover(Config, BeamFiles, SrcModules) ->
perform_cover(rebar_config:get(Config, cover_enabled, false),
Config, BeamFiles, SrcModules).
@@ -486,7 +517,7 @@ cover_write_index(Coverage, SrcModules) ->
cover_write_index_section(_F, _SectionName, []) ->
ok;
cover_write_index_section(F, SectionName, Coverage) ->
- %% Calculate total coverage %
+ %% Calculate total coverage
{Covered, NotCovered} = lists:foldl(fun({_Mod, C, N}, {CAcc, NAcc}) ->
{CAcc + C, NAcc + N}
end, {0, 0}, Coverage),
@@ -548,14 +579,18 @@ percentage(0, 0) ->
percentage(Cov, NotCov) ->
integer_to_list(trunc((Cov / (Cov + NotCov)) * 100)) ++ "%".
-get_app_names() ->
- [AppName || {AppName, _, _} <- application:loaded_applications()].
+%%
+%% == reset_after_eunit ==
+%%
status_before_eunit() ->
Apps = get_app_names(),
AppEnvs = [{App, application:get_all_env(App)} || App <- Apps],
{erlang:processes(), erlang:is_alive(), AppEnvs, ets:tab2list(ac_tab)}.
+get_app_names() ->
+ [AppName || {AppName, _, _} <- application:loaded_applications()].
+
reset_after_eunit({OldProcesses, WasAlive, OldAppEnvs, _OldACs}) ->
IsAlive = erlang:is_alive(),
if not WasAlive andalso IsAlive ->
diff --git a/test/rebar_eunit_tests.erl b/test/rebar_eunit_tests.erl
index 769a4cd..fb01a49 100644
--- a/test/rebar_eunit_tests.erl
+++ b/test/rebar_eunit_tests.erl
@@ -129,7 +129,7 @@ eunit_with_suites_and_tests_test_() ->
?_assert(string:str(RebarOut,
"myapp_mymod3:mygenerator_test_/0") =/= 0)},
- {"Selected suite's generator test raises an error",
+ {"Selected suite's generator test raises an error",
?_assert(string:str(RebarOut,
"assertEqual_failed") =/= 0)},