Need help with file structure

I have this project

|-- lib
|   |-- foo
|   |   |-- bar.ml
|   |   |-- bar.mli
|   |   |-- baz.ml
|   |   |-- baz.mli
|   |   |-- dune
|   |-- lib.ml
|   |-- dune
|-- test
|   |-- foo_test
|   |   |-- bar_test.ml
|   |   |-- baz_test.ml
|   |   |-- dune
|   |-- lib_test.ml
|   |-- dune
|-- dune-project

In each of the dune file

; lib/foo/dune
(library
  (name foo))
; lib/dune
(library
  (name lib)
  (public_name lib))
; test/foo_test/dune
(test
  (name foo_test)
  (libraries alcotest foo))
; test/dune
(test
  (name lib_test)
  (libraries alcotest lib))

In the root, I tried to run dune utop lib and I can see the modules

Foo__Bar
Foo.Bar
Foo__Baz
Foo.Baz

I tried to run dune runtest and it says

2 |  (name foo_test)
           ^^^^^^^^^^^^^^^^
Error: Module "Foo_test" doesn't exist.

I then try to create an empty file test/foo_test/foo_test.ml, and do dune runtest, it seems that nothing is happening. I have the Alcotest run function in the test/foo_test/bar_test.ml and test/foo_test/baz_test.ml

I have a few question:

  1. Why it says module Foo_test doesn’t exist? I follow the same structure as in lib and it worked in lib
  2. Why the test doesn’t run
  3. It seems that OCaml project structure is not that intuitive to me (coming from NodeJS), any resources I can read on this?

Could you create a git repo with this structure? I know you’re tring your best to describe it but it would be just faster/less error prone if we could just clone it and explain things easier.

The test might not be running because dune runtest does not re-run tests that successfully finished if nothing changed - it assumes the test result won’t change. Maybe dune runtest --force will solve your confusion?

2 Likes

Ah okay, thank you. I was thinking it would be too much a hassle to ask people to read my git.

But I actually figured it out! I spent time reading more about dune stanzas and it cleared up things for me now!

Thank you.

Could you post your solution? It might be useful to other people encountering a similar problem in the future and stumbling over this thread. Or the documentation of dune could be improved.

Try generating a blank project from scratch using dune init proj foo and look at how the name for the project gets included in the various dune files. The name for the library foo should match the name in the tests for that library.

$ cat lib/dune 
(library
 (name lib))
....
$ cat test/dune 
(test
 (name lib))

For the lib/foo code I usually make that a sub-component within the top level foo library eg

(library
 (public_name lib.foo)
 (name foo)
 (libraries ....))

Then you refer to lib.foo in your dune file to depend on it. We use a larger example of that arrangement in ocaml-ci. As @Leonidas mentioned a git repo would be easier to debug there are some subtleties involved that can cause issues.