Erlang 为什么Eunit不要求导出测试函数?
我正在阅读中的EUnit一章,从所有代码示例中我注意到的一件事是,Erlang 为什么Eunit不要求导出测试函数?,erlang,eunit,Erlang,Eunit,我正在阅读中的EUnit一章,从所有代码示例中我注意到的一件事是,-export()子句中从未声明过测试函数 为什么EUnit能够选择这些测试功能?: 在Erlang模块中使用EUnit的最简单方法是在模块开头添加以下行(在-module声明之后,但在任何函数定义之前): 这将产生以下效果: 创建导出函数test()(除非测试已关闭,且模块尚未包含test()函数),该函数可用于运行模块中定义的所有单元测试 使名称匹配的所有函数自动从模块导出(除非关闭测试,或定义了EUNIT\u NOAUT
-export()
子句中从未声明过测试函数
为什么EUnit能够选择这些测试功能?:
在Erlang模块中使用EUnit的最简单方法是在模块开头添加以下行(在-module
声明之后,但在任何函数定义之前):
这将产生以下效果:
- 创建导出函数
(除非测试已关闭,且模块尚未包含test()函数),该函数可用于运行模块中定义的所有单元测试test()
- 使名称匹配的所有函数自动从模块导出(除非关闭测试,或定义了
宏)EUNIT\u NOAUTO
很高兴我发现了这个问题,因为它为我提供了一种有意义的拖延方式,我想知道函数是如何动态创建和导出的 首先查看Erlang/OTP Github repo中影响EUnit的最新提交,即。(这样做的唯一原因是找到一个相对稳定的锚,而不是git分支。) 0包含EUnit的头文件 根据本文,第一步是
-include_lib(“eunit/include/eunit.hrl”)。
在测试的模块中,所以我假设这就是神奇发生的地方
1.(第79-91行)
1.1编译({parse_transform,eunit_autoexport})是什么意思?
从Erlang参考手册的模块章节():
-编译(选项)。
编译器选项。选项是单个选项或选项列表。在以下情况下,此属性将添加到选项列表中: 编译模块。请参阅编译器中的手册页 关于:
{parse_transform,Module}
导致解析转换函数 模块:parse_transform/2将应用于 检查代码是否有错误 从模块中: 此模块执行Erlang代码的标识解析转换。 它是作为一个示例提供给希望编写自己的代码的用户的 解析变压器。如果选项
{parse_transform,Module}
被传递给
编译器,一个用户编写的函数parse_transform/2
,由
在检查代码是否有错误之前,先检查编译器
基本上,如果模块M包含{parse_transform,module}
编译选项,那么可以使用模块:parse_transform/2
的实现来迭代M的所有函数和属性。它的第一个参数是Forms
,这是在Erlang中描述的M的模块声明(如中所述)
2.
此模块仅导出parse\u transfrom/2
以满足{parse\u transform,module}
编译选项,其首要任务是确定测试用例函数和生成器的配置后缀。如果未手动设置,则分别使用\u test
和\u test
(via)
然后,它使用扫描模块的所有函数和属性,并构建一个要导出的函数列表,其中上面的后缀匹配(加上原始函数。这一点我可能错了…)
最后,从原始的Forms
(作为第一个参数提供给)和要导出的函数列表(由上面的form/5
提供)构建一个模块声明。在该声明上插入了中提到的test/0
函数
-include_lib("eunit/include/eunit.hrl").
%% Parse transforms for automatic exporting/stripping of test functions.
%% (Note that although automatic stripping is convenient, it will make
%% the code dependent on this header file and the eunit_striptests
%% module for compilation, even when testing is switched off! Using
%% -ifdef(EUNIT) around all test code makes the program more portable.)
-ifndef(EUNIT_NOAUTO).
-ifndef(NOTEST).
-compile({parse_transform, eunit_autoexport}).
-else.
-compile({parse_transform, eunit_striptests}).
-endif.
-endif.