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