# Dune Cram tests: preloading aliases/scripts

**URL:** <https://discuss.ocaml.org/t/dune-cram-tests-preloading-aliases-scripts/17610>\
**Category:** Ecosystem\
**Tags:** cram, dune\
**Created:** [December 19, 2025, 8:33am UTC](https://discuss.ocaml.org/t/dune-cram-tests-preloading-aliases-scripts/17610 "2025-12-19T08:33:52Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![amaro](https://avatars.discourse-cdn.com/v4/letter/a/9fc348/32.png) [@amaro](https://discuss.ocaml.org/u/amaro)\
**Post date:** [December 19, 2025, 8:33am UTC](https://discuss.ocaml.org/t/dune-cram-tests-preloading-aliases-scripts/17610/1 "2025-12-19T08:33:52Z")

</div>

We are considering large-scale adoption of Cram tests, but we are missing some engineering features that are needed to ensure we don’t have to manually update hundreds of files when we need to apply some global changes.

For instance, in several of our tests, we need to build a small OCaml module before running tests with it. So we currently have several tests which start with:

```
$ dune build --root . --disable-cache _build/default/foo.cmxs

```

We’d like to “wrap” some of this in an alias or shell function, to ensure that all tests uniformly include the same options and future changes will be automatically propagated to all of them. To sum up, we want a preamble of some sort.

For instance, we could define a `cram_preamble.sh` file and then run:

```
$ source cram_preamble.sh

```

In fact, it looks more like this:

```
$ source ../../../../../../../cram_preamble.sh

```

Because we are starting at `build/.sandbox/57632bdb88b19d3ee68c697d605883ba/default/tests/foo/mytest.t`.

Besides the ugliness, one of the issues is that our Cram tests are stored in several different directories, with different nesting levels, so the number of `../` will vary per test.

Overall, this seems doable, but I wonder if I’m missing a simpler way to do things. Maybe I can do something with the `cram` stanza in a dune file? Or using the `runtest` alias?

---

<div class="post-metadata">

**Author:** ![Chimrod](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/chimrod/32/6042_2.png) [@Chimrod](https://discuss.ocaml.org/u/Chimrod)\
**Post date:** [December 19, 2025, 12:57pm UTC](https://discuss.ocaml.org/t/dune-cram-tests-preloading-aliases-scripts/17610/2 "2025-12-19T12:57:58Z")

</div>

In my project, I use this trick to add a test library in the path:

My dune file contains this code:

```auto
; Add the test library in the path

(env
 (_
  (binaries %{project_root}/test/tests.exe)))

; And depend of it. The binary will be available in the
; cram tests under the name "tests"

(cram
 (deps %{bin:tests}))

```

This is the [part of the dune documentation](https://dune.readthedocs.io/en/stable/reference/dune/env.html) which defines the trick:

> `(binaries <binaries>)`, where `<binaries>` is a list of entries of the form `(<filepath> as <name>)`. `(<filepath> as <name>)` makes the binary `<filepath>` available in the command search as just `<name>`. For instance, in a `(run <name> ...)` action, `<name>` will resolve to this file path. You can also write just the file path, in which case the name will be inferred from the basename of `<filepath>` by dropping the `.exe` suffix, if it exists. For example, `(binaries bin/foo.exe (bin/main.exe as bar))` would add the commands `foo` and `bar` to the search path.

---

<div class="post-metadata">

**Author:** ![rgrinberg](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/rgrinberg/32/40_2.png) [@rgrinberg](https://discuss.ocaml.org/u/rgrinberg)\
**Post date:** [December 19, 2025, 10:17pm UTC](https://discuss.ocaml.org/t/dune-cram-tests-preloading-aliases-scripts/17610/3 "2025-12-19T22:17:39Z")

</div>

The dune team has been running into this problem for a while now as well, and we’ve recently sought a solution. Starting from version 3.21, you’ll be able to write:

```auto
(cram
 (setup_scripts cram_preamble.sh))

```

And have this shell script be sourced in every single cram test this stanza is applied to.

Here are the [docs](https://github.com/ocaml/dune/pull/13010/changes), but there’s not much more to it than what I’ve just described.

---

<div class="post-metadata">

**Author:** ![amaro](https://avatars.discourse-cdn.com/v4/letter/a/9fc348/32.png) [@amaro](https://discuss.ocaml.org/u/amaro)\
**Post date:** [January 14, 2026, 12:54pm UTC](https://discuss.ocaml.org/t/dune-cram-tests-preloading-aliases-scripts/17610/4 "2026-01-14T12:54:43Z")

</div>

Thanks! It will be very useful when we can force our users to upgrade to dune 3.21.

Until then, I found out that using `$DUNE_SOURCEROOT`, which I didn’t know exist, allows setting up a not-so-ugly path:

```
  $ source $DUNE_SOURCEROOT/cram_prelude.sh

```

But it’ll definitely be better to use the `setup_scripts` stanza.

---

<div class="post-metadata">

**Author:** ![andreypopp](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/andreypopp/32/97_2.png) [@andreypopp](https://discuss.ocaml.org/u/andreypopp)\
**Post date:** [January 14, 2026, 1:13pm UTC](https://discuss.ocaml.org/t/dune-cram-tests-preloading-aliases-scripts/17610/5 "2026-01-14T13:13:34Z")

</div>

> [@amaro](#):
>
> Until then, I found out that using `$DUNE_SOURCEROOT`, which I didn’t know exist, allows setting up a not-so-ugly path:

I think, if you don’t define a dependency on this file, then tests won’t re-run when the file changes. That can be confusing and non obvious to debug.

---

<div class="post-metadata">

**Author:** ![amaro](https://avatars.discourse-cdn.com/v4/letter/a/9fc348/32.png) [@amaro](https://discuss.ocaml.org/u/amaro)\
**Post date:** [April 29, 2026, 1:55pm UTC](https://discuss.ocaml.org/t/dune-cram-tests-preloading-aliases-scripts/17610/6 "2026-04-29T13:55:05Z")

</div>

We just tried using that feature, but something is not working as expected: we have a single preamble script in `dev/init-cram.sh` and we try to include it from all of our Cram tests, as in:

```auto
; Generic rules for all cram tests
(cram
  (setup_scripts ../dev/init-cram.sh)
)

```

But the tests do not see the environment variables exported in `init-cram.sh`. Also, I don’t know if we can use `DUNE_SOURCEROOT` somewhere.

Is such a relative path supposed to work, or is that something that is currently unsupported?
