在多文件项目中使用dune + qtest



让我先说一下,我是一个完全的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

我首先认为这意味着我组织文件的方式不正确。但是,我可以在mylib.ml中访问Helper.bar:

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

因此我不知道的问题可以在这里。这是怎么呢

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

(modules)

在沙丘文件中(如您在这里看到的)

你的沙丘文件看起来像:

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

Dune默认将库封装在与库同名的模块中。例如,用

定义mylib
a.ml
b.ml

将创建一个Mylib模块,AB作为子模块。但是,如果您手工定义mylib模块,请认为该模块是库的入口点,您有责任公开所有可见的子模块。因此,如果您将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)
)
)

(我希望我错过了一个选项,并且有一个更简单的解决方案来发送一个标志到运行器生成器)

相关内容

  • 没有找到相关文章

最新更新