EUnit无法测试私有函数

6
我正在为 Erlang 代码编写 EUnit 测试。
我有一个源模块:
-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.
...
...
...

一个单元测试模块:
-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)).
...
...
...

当我运行eunit:test(prob_list,[verbose])时,它会显示:
 prob_list_tests: probability_test...*failed*
::undef

但是,当我在我的prob_list模块中导出probability/2时,一切正常。
有没有任何方法来测试私有函数?
3个回答

6

您可以使用指令-compile(export_all)来有条件地导出所有函数,只有在编译测试时才生效,详见EUnit宏

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

6
我通常使用的方法是将所有单元测试包含在同一个文件中,然后将它们分离出来:
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
-endif.
%% 函数 [...]
-ifdef(TEST). %% 单元测试在这里。 -endif.
这样可以让您在测试公共函数的同时测试私有函数。

我已经按照你写的做了一切,但是我得到了相同的结果。我运行 erlc -DTEST *.erl 进行编译,但仍然从私有函数中得到 ::undef。 - Uko
好的,我的错,我忘记在测试中从函数调用中删除模块名称了。 - Uko
这使得保持Erlang文件的清晰和可读性非常困难。 建议将测试用例保存在单独的文件中,并采取Phil建议的方法。 - Trisha Chatterjee

3

好的,下面开始翻译:

dclements 给了我一个不错的提示,让我知道如何实现我所要求的功能。我不想把所有测试都放在源模块中,你可以在这里看到一个很好的例子来保持它们的分离:Erlang EUnit – introduction

现在我的解决方案是在 TEST 编译时导出所有函数。因此,你需要输入如下内容:

-define(NOTEST, true).

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

然后使用 erlc -DTEST *.erl 编译以运行测试,普通编译只导出必要的函数。


1
这是一个合理的方法(尽管值得注意的是,您可以有多个导出行,这可能会使事情变得更清晰),特别是如果您想将单元测试分离到单独的文件中并测试私有函数。这种方法的一个缺点是,如果您意外地在测试文件之外使用私有方法,则可能会导致通过测试但无法运行的代码。 - David H. Clements
1
为了将所有内容暴露给测试模块,您可以使用"-compile(export_all)",而不是维护一个大的导出语句。 - goertzenator

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接