1

首先让我说我是 OCaml 的一个完整的初学者,所以如果我似乎做出了一些奇怪的选择,我很可能没有意识到它们是一个选择。

我正在尝试在我的项目中进行单元测试。经过一番搜索,我决定了qtest.lib

我的项目设置如下:

$ mkdir mylib
$ cd mylib
$ dune init lib mylib

dune文件中,我写道:

(library
 (name mylib)
 (inline_tests (backend qtest.lib)))

mylib.ml中,我输入了以下代码:

let foo x = x + 2

(*$T foo
  foo 2 = 4
*)

此时,一切都按预期工作

$ dune runtest
Info: Creating file dune-project with this contents:
| (lang dune 2.9)
inline_test_runner_mylib alias runtest
random seed: 425752161
 [1 / 1] >foo>mylib.ml:4 *
 [1 / 1] >foo>;32;1mSUCCESS

如果我尝试在项目中引入另一个文件,问题就开始了。我创建helper.ml了以下内容:

let bar x = 3 * x

(*$T bar
  bar 3 = 9
*)

现在,dune runtest错误出来了

$ dune runtest
File "mylib.ml", line 11, characters 5-11:
Error: Unbound module Helper

在我复制它的其他一些尝试中,提到的文件是_build/default/.mylib.inline-tests/inline_test_runner_mylib.ml-gen.

我首先假设这意味着我错误地组织了我的文件。但是,我可以Helper.bar访问mylib.ml

$ cat mylib.ml
let foo x = Helper.bar (x + 2)
$ dune build     # no errors

因此,我不知道这里可能出现什么问题。这是怎么回事?

4

2 回答 2

0

奇怪的是,它看起来像你需要把

(modules)

在你的沙丘文件中(你可以在这里看到)

您的沙丘文件将如下所示:

(library
 (name mylib)
 (modules)
 (inline_tests (backend qtest.lib)))
于 2021-10-10T19:25:18.860 回答
0

Dune 默认将 library 包装在与 library 同名的模块中。例如,定义一个mylib

a.ml
b.ml

将创建一个Mylib带有AB作为子模块的模块。但是,如果您mylib手动定义一个模块,dune 会认为该模块是您库的入口点,并且您有责任公开所有可见的子模块。因此,如果您定义mylib.ml为:

let x = 0

您明确隐藏了Helper模块。这里更简单的选择可能是重命名Mylib模块。

另一个问题是 qtest 后端似乎不知道沙丘包装库。一个潜在的解决方法是定义您自己的内联测试后端并open Mylib在序言中添加一个


(library (name myqtest)
 (modules)
 (inline_tests.backend
  (runner_libraries qcheck ounit2 bytes)
  (generate_runner (run qtest extract --preamble "open Myib" --quiet  %{impl-files} %{intf-files}))
 )
)

(library (name mylib) 
 (inline_tests
  (backend myqtest)
 )
)

(我希望我错过了一个选项,并且有一个更简单的解决方案可以向跑步者生成器发送标志)

于 2021-10-11T13:38:48.490 回答