使用通用测试的模块的 Erlang 测试(非导出/私有)功能

Posted

技术标签:

【中文标题】使用通用测试的模块的 Erlang 测试(非导出/私有)功能【英文标题】:Erlang Testing (Non Exported / Private) function of module using common test 【发布时间】:2013-03-04 05:39:49 【问题描述】:

我在 Erlang 中有一个模块,它具有 Erlang 未导出的功能。 如何使用通用测试框架测试/调用这些函数?

【问题讨论】:

【参考方案1】:

这是不可能的。您可以使用-ifdef(TEST). 预处理器条件仅在编译测试时导出这些函数。

根据您的工具,您可能需要在编译模块时显式提供 TEST 宏。您可以使用 d,'TEST' 编译器选项或 -DTEST 编译标志来做到这一点。

【讨论】:

我试过这个 -ifdef(TEST)。 -export([ generate_perm_list/2 ])。 -万一。在我的模块中,但似乎 TEST 宏未在常见测试中定义。 Common Test 中是否定义了其他宏? 您需要编译您的模块以使用您自己定义的 TEST 宏进行测试。您可以使用d,'TEST' 编译器选项或 -DTEST 编译标志来做到这一点。【参考方案2】:

Common Test 很棘手,但可以使用嵌入式EUnit 测试用例来测试模块中的私有函数。然后,您可以使用 Common Test 测试公共接口。 Rebar 将在您运行 rebar test 时自动发现嵌入式测试用例。

这是一个例子:

-module(example).

-export([public/1]).

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

%% This function will be tested externally using Common Test
public(Foo) ->
    private(Foo + 42).

%% This function is not reachable to CT, so it will be tested using EUnit.
private(Bar) ->
    Bar * 2.

%%% Tests
-ifdef(TEST).

private_test() ->
    ?assertEqual(10, private(5)),
    ?assertEqual(0, private(0)).

-endif.

附带说明一下,如果您在使用 EUnit 进行测试时需要模拟掉一个模块(或其中的一部分),您可能会喜欢 Meck。

有关 EUnit 的简要介绍,请参阅 Learn You Some Erlang chapter。

【讨论】:

【参考方案3】:

您可以将私有函数放在它们自己的模块中,然后导出所有这些函数。原始模块可以导入它们并且它们将保持私有,您的测试框架可以直接调用导入私有模块。

【讨论】:

【参考方案4】:

以防万一有人也遇到这种情况。包含 eunit.hrl 文件会定义 TEST,除非在包含之前定义了 NOTEST。 -include_lib("eunit.hrl")。 参考:http://www.erlang.org/download/eunit.hrl

【讨论】:

以上是关于使用通用测试的模块的 Erlang 测试(非导出/私有)功能的主要内容,如果未能解决你的问题,请参考以下文章

如何访问和测试 node.js 模块中的内部(非导出)函数?

管理Erlang应用程序中的配置

在没有导出的情况下测试打字稿模块

Kotlin 多平台项目在 IDEA 中运行通用模块测试

检查通过 rewire 可见的(私有/非导出)函数上的方法调用

在不通过通用测试的情况下杀死 gen_server