Testing And Benchmarking in OCaml

Here’s the translation of the Go testing and benchmarking example to OCaml:

Unit testing is an important part of writing principled OCaml programs. The OUnit2 library provides the tools we need to write unit tests.

For the sake of demonstration, this code is in a single file, but it could be split into separate files. Testing code typically lives in a separate file from the code it tests.

open OUnit2

(* We'll be testing this simple implementation of an integer minimum. *)
let int_min a b =
  if a < b then a else b

(* A test is created by writing a function that uses assertions. *)
let test_int_min_basic _ =
  assert_equal (-2) (int_min 2 (-2)) ~msg:"int_min 2 (-2) should be -2"

(* Writing tests can be repetitive, so it's idiomatic to use a table-driven style,
   where test inputs and expected outputs are listed in a table and a single function
   walks over them and performs the test logic. *)
let test_int_min_table _ =
  let test_cases = [
    (0, 1, 0);
    (1, 0, 0);
    (2, -2, -2);
    (0, -1, -1);
    (-1, 0, -1);
  ] in
  List.iter (fun (a, b, expected) ->
    assert_equal expected (int_min a b)
      ~msg:(Printf.sprintf "int_min %d %d should be %d" a b expected)
  ) test_cases

(* Benchmark tests in OCaml typically use the Core_bench library. 
   Here's a simple example of how you might benchmark the int_min function. *)
let bench_int_min () =
  Core_bench.Bench.Test.create ~name:"int_min" (fun () ->
    ignore (int_min 1 2)
  )

(* Define the test suite *)
let suite =
  "int_min_tests" >::: [
    "test_basic" >:: test_int_min_basic;
    "test_table" >:: test_int_min_table;
  ]

(* Run the tests *)
let () =
  run_test_tt_main suite;
  Core.Command.run (Core_bench.Bench.make_command [bench_int_min ()])

To run the tests, you would typically use a build system like dune. Here’s an example dune file:

(test
 (name int_min_tests)
 (libraries ounit2 core core_bench))

Then you can run the tests with:

$ dune test

And to run the benchmarks:

$ dune exec ./int_min_tests.exe -- -bench

This will run all the tests and then the benchmarks. The output will show the results of the tests and the performance of the benchmarked function.

Note that OCaml’s approach to testing and benchmarking is somewhat different from Go’s. OCaml typically uses external libraries for these tasks, while Go has built-in testing and benchmarking facilities. The concepts, however, remain similar: you write test functions to verify correctness and benchmark functions to measure performance.