我在OCaml中有许多"库"模块(主要是实用程序和辅助函数),我在最后添加了以下类型的代码以进行简单的单元测试:
let main () = ...
main
Run Code Online (Sandbox Code Playgroud)
要么
let () = ...
Run Code Online (Sandbox Code Playgroud)
这是主要打印到控制台的代码(用于简单的测试目的).现在的问题是,当我将"库"模块与我的"主"模块链接并执行程序时,我得到了所有这些令人分心的测试消息.有没有办法在OCaml模块中包含代码,该模块在单独链接模块时执行(从而促进琐碎的测试),但在用作"库"时却没有?我已经读过SO中的帖子,表示OCaml没有"主"模块的概念,并且所有模块都是相同的,但在我看来,给链接器的目标文件的顺序可以解释为表明最后一个模块是"主要"模块(因为它位于"依赖食物链"的顶部).
OCaml支持静态链接和模块的动态加载; 你通常做什么(以及什么是类型安全)是静态链接.如果您需要某种插件架构,我只会建议动态加载.
无论如何,库只不过是一个模块(可能带有子模块).如果静态链接模块,则所有"主"例程将按可执行文件中链接的模块的顺序执行.
因此,如果你对它没有做任何事情,模块就不知道它以某种"神奇"的方式被链接到哪个可执行文件; 你应该做的是:
附录:
如果你用其他语言这样做,似乎也没有免费蛋糕:
在Java中,如果代码中有多个主管,则必须明确选择要运行可执行文件的主管.
在C中你可以使用C预处理器来做类似的事情
#ifdef TEST_1
int main() {
...
}
#endif
Run Code Online (Sandbox Code Playgroud)
OCaml有自己的预处理器camlp4(camlp4维基百科文章),你可以用它来做类似的事情.我个人认为这种测试嵌入是一种糟糕的软件工程.您应该从接口端测试您的模块/类/ ..并使用断言(存在于Java,C和OCaml中)标记内部不变量.
工具链没有任何规定,它会生成一个文件,在启动时按照链接的顺序运行所有模块的顶级代码.
我不知道如何让它系统地工作.模块几乎总是有一些需要执行的顶级代码.您需要一种方法将顶级代码分成两组(一组始终执行,另一组仅在模块是最后一个要链接的文件时执行).这似乎不必要地混乱.
更好的解决方案(在我看来)只是使用稍微复杂的测试框架.