EUnit fails to test private functions

1.2k views Asked by At

I'm writing EUnit tests for Erlang code.

I have a source module:

-module(prob_list).
-export([intersection/2,union/2]).

probability([], _Item) -> false;
probability([{First,Probability}|Rest], Item) ->
    if
        First == Item -> Probability;
        true          -> probability(Rest, Item)
    end.
...
...
...

and a unit-test module:

-module(prob_list_tests).
-include_lib("eunit/include/eunit.hrl").

-define(TEST_LIST,[{3,0.2},{4,0.6},{5,1.0},{6,0.5}]).
-define(TEST_LIST1,[{2,0.9},{3,0.6},{6,0.1},{8,0.5}]).
-define(TEST_UNO_LIST,[{2,0.5}]).

probability_test() -> ?assertNot(prob_list:probability([],3)),
                      ?assertEqual(0.5,prob_list:probability(?TEST_UNO_LIST,2)),
                      ?assertNot(prob_list:probability(?TEST_UNO_LIST,3)),
                      ?assertEqual(0.2,prob_list:probability(?TEST_LIST,3)),
                      ?assertEqual(1.0,prob_list:probability(?TEST_LIST,5)),
                      ?assertNot(prob_list:probability(?TEST_LIST,7)).
...
...
...

When I run eunit:test(prob_list,[verbose]) it says:

 prob_list_tests: probability_test...*failed*
::undef

but when I export probability/2 in my prob_list module, everything is ok.

Is there any way to test private functions?

3

There are 3 answers

2
Uko On BEST ANSWER

Ok, so here it goes:

dclements gave me a nice hint of how can I accomplish what I've asked. I don't want to put all my tests in source module, you can see a nice example of keeping the apart here: Erlang EUnit – introduction

Now my solution is to export all functions on TEST compilation. So you put:

-define(NOTEST, true).

-export([intersection/2,union/2]).
-ifdef(TEST).
-export([intersection/2,union/2,contains/2,probability/2,lesslist/2]).
-endif.

And then compile with erlc -DTEST *.erl to run tests, and ordinary compile to export only needed functions.

3
David H. Clements On

The general approach that I use for this is to include all of the unit tests in the same file and the separate them out:

-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
-endif.

%% Functions
[...]


-ifdef(TEST).
%% Unit tests go here.
-endif.

This should allow you to test your private functions alongside your public functions.

0
Phil Calvin On

You can use the directive -compile(export_all) to conditionally export all functions only when compiling for testing:

%% Export all functions for unit tests
-ifdef(TEST).
-compile(export_all).
-endif.