Let me begin by saying that I'm a complete beginner in OCaml, so if I seem to have made some weird choices, I'm most likely not aware of them being a choice.
I am trying to get unit testing working in my project. After some searching I settled on qtest.lib
.
I've set up my project as follows:
$ mkdir mylib
$ cd mylib
$ dune init lib mylib
In the dune
file, I've written:
(library
(name mylib)
(inline_tests (backend qtest.lib)))
In mylib.ml
, I've put the following code:
let foo x = x 2
(*$T foo
foo 2 = 4
*)
At this point, everything works as expected:
$ 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
The issues start if I try to introduce another file into the project. I created helper.ml
with the following contents:
let bar x = 3 * x
(*$T bar
bar 3 = 9
*)
Now, dune runtest
errors out with
$ dune runtest
File "mylib.ml", line 11, characters 5-11:
Error: Unbound module Helper
In some of my other attempts at reproducing it, the file mentioned was instead _build/default/.mylib.inline-tests/inline_test_runner_mylib.ml-gen
.
I first assumed that this means I'm organizing my files incorrectly. However, I can access Helper.bar
within mylib.ml
:
$ cat mylib.ml
let foo x = Helper.bar (x 2)
$ dune build # no errors
Thus I have no idea what the problem could be here. What's going on?
CodePudding user response:
Strangely it looks like you need to put
(modules)
in your dune file (as you can see here)
Your dune file will look like:
(library
(name mylib)
(modules)
(inline_tests (backend qtest.lib)))
CodePudding user response:
Dune wraps library by default in a module with the same name as the library. For instance, defining a mylib
library with
a.ml
b.ml
will create a Mylib
module with A
and B
as submodule.
However, if you define a mylib
module by hand, dune consider that this module is the entry point of your library, and it is your responsibility to expose all visible submodule.
Thus if you define mylib.ml
as:
let x = 0
you are explicitly hiding the Helper
module.
The simpler option here is probably to rename the Mylib
module.
Another issue is that the qtest backend does not seem aware of dune wrapping libraries. A potential workaround is to define your own inline test backend and add an open Mylib
to the preamble
(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)
)
)
(I hope that I am missing an option and that there is a simpler solution to send a flag to the runner generator)