我正在阅读EUnit在给你学点二郎中的章节,我从所有的代码示例中注意到一件事:测试函数从未在-export()子句中声明过。
为什么EUnit能够选择这些测试函数?
发布于 2016-03-26 16:33:29
从文件中
在Erlang模块中使用EUnit的最简单方法是在模块的开头添加以下行(在
-module声明之后,但在任何函数定义之前): -include_lib("eunit/include/eunit.hrl")。 这将产生以下效果:
test() (除非关闭测试,并且模块尚未包含test()函数),该函数可用于运行模块中定义的所有单元测试。..._test()或..._test_() 匹配的函数自动从模块中导出(除非关闭测试或定义EUNIT_NOAUTO宏)发布于 2018-11-14 00:43:10
很高兴我找到了这个问题,因为它为我提供了一种有意义的拖延方式,我想知道如何动态地创建和导出函数。
首先,查看影响Erlang/OTP中的EUnit的最新提交,即4273。(唯一的原因是找到一个相对稳定的锚,而不是git分支。)
0。包含EUnit的头文件
根据EUnit用户指南,第一步是测试模块中的-include_lib("eunit/include/eunit.hrl").,所以我假设这就是魔术发生的地方。
1. otp/lib/eunit/include/eunit.hrl (第79-91行)
%% 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.1.1 -compile({parse_transform, eunit_autoexport}).是什么意思?
来自Erlang参考手册的模块章节(预定义模块属性):
-compile(Options).编译器选项。选项是单个选项或选项列表。此属性在编译模块时添加到选项列表中。请参阅编译器中的汇编(3)手册页面。
转到汇编(3)
{parse_transform,Module}在检查代码是否有错误之前,将解析转换函数模块: parsed /2应用于分析过的代码。
来自erl_id_trans模块:
该模块执行Erlang代码的标识解析转换。对于想要编写自己的解析转换器的用户来说,它是一个示例。如果将选项
{parse_transform,Module}传递给编译器,编译器将在检查代码是否存在错误之前调用用户编写的函数parse_transform/2。
基本上,如果模块M包括{parse_transform, Module}编译选项,那么可以通过使用Module:parse_transform/2的实现来迭代M的所有函数和属性。它的第一个参数是Forms,它是在Erlang的抽象格式中描述的M的模块声明(用Erlang运行时系统应用(ERTS)用户指南描述)。
2. otp/lib/eunit/src/eunit_autoexport.erl
这个模块只输出parse_transfrom/2以满足{parse_transform, Module}编译选项,它的首要任务是找出测试用例函数和生成器的配置后缀。如果不手动设置,则分别使用_test和_test_ (通过lib/eunit/src/eunit_internal.hrl)。
然后,它使用eunit_autoexport:form/5扫描模块的所有函数和属性,并在上面的后缀匹配(加上原始函数)的情况下构建要导出函数的列表。我可能错了.)。
最后,eunit_autoexport:rewrite/2从原始的Forms (作为第一个参数提供给eunit_autoexport:parse_transform/2 )和要导出的函数列表(由form/5提供)构建一个模块声明。在第82行上,它注入EUnit文档中提到的test/0函数。
https://stackoverflow.com/questions/36237543
复制相似问题