marmistrz
marmistrz

Reputation: 6404

The correct way to write unit tests for a module in OCaml

I have a given interface specification in the module.mli file. I have to write its implementation in the module.ml file.

module.mli provides an abstract type

type abstract_type

I'm using OUnit to create the tests. I need to use the type's implementation in them. (for example to compare the values) One solution would be to extend the interface to contain additional functions used in the tests.

But is it possible to do such a thing without modifying the interface?

Upvotes: 5

Views: 2750

Answers (1)

Martin Jambon
Martin Jambon

Reputation: 4939

The only way to expose tests without touching the module interface would be to register the tests with some global container. If you have a module called Tests that provides a function register, your module.ml would contain something like this:

let some_test = ...

let () = Tests.register some_test

I don't recommend this approach because the Tests module loses control over what tests it's going to run.

Instead I recommend exporting the tests, i.e. adding them to module.mli.

Note that without depending on OUnit, you can export tests of the following type that anyone can run. Our tests look like this:

let test_cool_feature () =
  ...
  assert ...;
  ...
  assert ...;
  true

let test_super_feature () =
  ...
  a = b

let tests = [
  "cool feature", test_cool_feature;
  "super feature", test_super_feature;
]

The interface is:

...
(**/**)
(* begin section ignored by ocamldoc *)

val test_cool_feature : unit -> bool
val test_super_feature : unit -> bool
val tests : (string * (unit -> bool)) list

Upvotes: 6

Related Questions