# Automated Unit and integration test frameworks

**URL:** <https://discuss.ocaml.org/t/automated-unit-and-integration-test-frameworks/4891>\
**Category:** Learning\
**Created:** [December 19, 2019, 11:44am UTC](https://discuss.ocaml.org/t/automated-unit-and-integration-test-frameworks/4891 "2019-12-19T11:44:18Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mohan\_Radhakrishnan](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mohan_radhakrishnan/32/1905_2.png) [@Mohan\_Radhakrishnan](https://discuss.ocaml.org/u/Mohan_Radhakrishnan)\
**Post date:** [December 19, 2019, 11:44am UTC](https://discuss.ocaml.org/t/automated-unit-and-integration-test-frameworks/4891/1 "2019-12-19T11:44:18Z")

</div>

Hello,  
I am looking for automated unit and integration testing frameworks and methods for Ocaml. My IDE is emacs + tuareg + merlin. I can try VS Code too.  
But I was coding examples. Now I want to build a project, pull from git and run tests. What is the recommended way to do this ?

I also read about ‘dune’ in this forum. Is that the proper build and dependency management system ?

Thanks,  
Mohan

---

<div class="post-metadata">

**Author:** ![Mohan\_Radhakrishnan](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mohan_radhakrishnan/32/1905_2.png) [@Mohan\_Radhakrishnan](https://discuss.ocaml.org/u/Mohan_Radhakrishnan)\
**Post date:** [December 25, 2019, 2:41pm UTC](https://discuss.ocaml.org/t/automated-unit-and-integration-test-frameworks/4891/2 "2019-12-25T14:41:32Z")

</div>

So now I have set up dune to build the code. I thought Dune will pull dependencies from an external public repository like _Maven_.does That was what I asked earlier. Appears that I have to install OUnit using opam first.  
I thought that the dependency management system will somehow setup the editor to load the dependencies and I can just use _open OUnit2_  
Eclipse and IntelliJ have spoilt me.

---

<div class="post-metadata">

**Author:** ![shonfeder](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/shonfeder/32/424_2.png) [@shonfeder](https://discuss.ocaml.org/u/shonfeder)\
**Post date:** [December 26, 2019, 1:15am UTC](https://discuss.ocaml.org/t/automated-unit-and-integration-test-frameworks/4891/3 "2019-12-26T01:15:33Z")

</div>

`dune` does the builds (so takes care of build dependencies) but `opam` does the packaging. `opam` in conjunction with `tuareg` does indeed ensure that the editor knows about new deps, but it’s true you need to go through opam to install them. I usually have a terminal open with `dune build -w` running, so it will rebuild on any changes, and ensure dependencies are kept up to date (e.g., if I add a new module or component somewhere in the project).

For testing, I am fond of [qcheck](https://github.com/c-cube/qcheck) for property based testing and [alcotest](https://github.com/mirage/alcotest) for the test runner and unit tests. But OUnit is widely used, so I’m sure this is a good choice 🙂

re: test automation, I have used circleCI for automating CI without much fuss. You can see my approach [here](https://github.com/shonfeder/alg_structs/blob/master/.circleci/config.yml). You may also be interested in the new GitHub actions announced in [GitHub Actions for OCaml / opam now available](https://discuss.ocaml.org/t/github-actions-for-ocaml-opam-now-available/4745)

I think better opam/dune integration (or a wrapper tool to manage their interaction) will be coming before long, and it will make it much easier to manage dependencies. In the meantime, I have taken to including a `Makefile` with a rule like this:

```auto
.PHONY: deps
deps: $(opam_file)

# Update the package dependencies when new deps are added to dune-project
$(opam_file): dune-project
	-dune build @install # Update the $(opam_file)
	-git add $(opam_file) # opam uses the state of master for it updates
	-git commit $(opam_file) -m "Updating package dependencies"
	opam install . --deps-only # Install the new dependencies

```

Then `make deps` will update the opam package file and install new deps as needed. This depends on [dune generation of opam files](https://dune.readthedocs.io/en/stable/opam.html#generating-opam-files).

---

<div class="post-metadata">

**Author:** ![Mohan\_Radhakrishnan](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mohan_radhakrishnan/32/1905_2.png) [@Mohan\_Radhakrishnan](https://discuss.ocaml.org/u/Mohan_Radhakrishnan)\
**Post date:** [December 30, 2019, 12:27pm UTC](https://discuss.ocaml.org/t/automated-unit-and-integration-test-frameworks/4891/4 "2019-12-30T12:27:35Z")

</div>

I set up Dune to build and execute my code. But I still have some questions. Hope I am not testing your patience 🙂

- I have a _.opam_ file and a dune file showing dependencies and module names. So without this _.opam_ file dune doesn’t build. What is meant when you mentiond that opam does the packaging and dune does the build ? Aren’t these both one and the same thing ? That is how I used to execute, run tests and package Java code.

- Could you point out how dune generates this _.opam_ file ? This is required by your `Makefile`

I am trying to understand the purpose of the 3 files dune-project, _.opam_ and dune. Looks like .opam has the build lifecycle instructions like Apache Maven’s pom.xml

Thanks,  
Mohan

---

<div class="post-metadata">

**Author:** ![shonfeder](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/shonfeder/32/424_2.png) [@shonfeder](https://discuss.ocaml.org/u/shonfeder)\
**Post date:** [December 30, 2019, 8:59pm UTC](https://discuss.ocaml.org/t/automated-unit-and-integration-test-frameworks/4891/5 "2019-12-30T20:59:46Z")

</div>

> [@Mohan\_Radhakrishnan](#):
>
> is meant when you mentiond that opam does the packaging and dune does the build ? Aren’t these both one and the same thing ?

Packaging is about _software deployment_, which is to say making a software system available for use. Building is about constructing programs that can be used from source code (in conjunction with whatever dependencies). These two things are related, but different. E.g., interpreted language like Python have package managers, but (arguably) there is no “building”, you just install new source code and run it. On the other extreme, binary package managers install pre-built artifacts, so while building is required to create the package, the package manager itself doesn’t involve a build phase. In source based package mangers, the border is easily blurred, since deploying some software means getting the source code onto the target machine and building it. It is common for language-specific tooling to combine source based package management and the build system into one too (or at least to wrap this for end users into one tool), but they are logically distinct areas of concern.

If you look in your `.opam` files, you will see see an entry like `build: ["dune" "build" ...]`. This tells opam ow to build the source of the package. It uses this instruction as part of its installation process. You could replace this with another build tool, like `make` or `ocamlbuild` or with just an invocation of ocamlc directly! But standard practice is now generally to use `dune`. (You could also package up ocaml code using a different package manager, like nix or pacman, in which case you might use dune but not opam).

> [@Mohan\_Radhakrishnan](#):
>
> So without this _.opam_ file dune doesn’t build.

I suspect this isn’t true: if you remove the `.opam` file in question dune will probably still build fine, assuming all the dependencies are already installed. What opam files are good for, however, is providing a portable definition of all the ocaml dependencies needed by a package. This lets you pull down the source code onto a new machine (whether real or virtual), and just do `opam install .` to have all the dependencies installed and the package built. (This is just a special case of “configuration as code”.)

> [@Mohan\_Radhakrishnan](#):
>
> Could you point out how dune generates this _.opam_ file ? This is required by your `Makefile`

See [Stanza Reference — Dune documentation](https://dune.readthedocs.io/en/stable/dune-files.html#generate-opam-files) and [https://dune.readthedocs.io/en/stable/opam.html#generating-opam-files](https://dune.readthedocs.io/en/stable/opam.html#generating-opam-files) for how to configure dune to generate opam files. Let me know if you have any followup questions about making use of that configuration.

> [@Mohan\_Radhakrishnan](#):
>
> I am trying to understand the purpose of the 3 files dune-project, _.opam_ and dune.

I’m not familiar with Java land, so I’m afraid I can’t help with comparison. But I can explain how these three files relate:

- `.opam` species a package for `opam`. A package includes some meta data about the project (like its name, the author, etc.) as well as a list of other opam packages required as dependencies. It also includes instructions on how to build and install the backage.
- `dune-project` specifies a software project that will be built with dune. A project can consist of one or more software components (libraries, tests, executables, data). It only supports a few pieces of meta data, and was recently extended to also enable generation of `.opam` files. If you enable this (as described above), you won’t need to think too much about the `.opam` file any more. See [Stanza Reference — Dune documentation](https://dune.readthedocs.io/en/stable/dune-files.html#dune-project) for documentation on this file.
- `dune` files specify components that can be built by dune. They describe the libraries that a component relies on, any preprocessors it uses, what executable or library it builds to, etc. See [Stanza Reference — Dune documentation](https://dune.readthedocs.io/en/stable/dune-files.html#dune) for documentation on `dune` files.

The reason for the distinction between opam dependencies and library dependencies in a `dune` file can be understood by considering this kind of example: an executable and library might both be defined in the same package, but the don’t necessarily share the same dependencies. The executable may need a CLI parsing library, but the internal library in the package won’t require this, so we’ll end up with the CLI parsering lib in the .opam file, but it will only show up in the dune file for the executable, not for the internal library.

If we started over from scratch, we’d probably have fewer moving parts to this whole system, but thankfully they are all converging into a nicely integrated set of tools, and things are improving all the time.
