Testing, Documentation & Debugging
Run dune test; if output differs, dune promote updates the expectation.
24.1 Alcotest (unit tests)
let test_add () = Alcotest.(check int) "same ints" 4 (2 + 2)
let test_rev () = Alcotest.(check (list int)) "rev" [3;2;1] (List.rev [1;2;3])
let () =
Alcotest.run "MyLib" [
"arith", [ Alcotest.test_case "add" `Quick test_add ];
"list", [ Alcotest.test_case "rev" `Quick test_rev ];
]24.2 Expect tests (ppx_expect)
Run dune test; if output differs, dune promote updates the expectation.
(library (name mylib) (inline_tests) (preprocess (pps ppx_expect)))let%expect_test "addition" =
print_int (1 + 2);
[%expect {| 3 |}]24.3 Inline tests
let%test "rev" = List.rev [1;2] = [2;1]
let%test_unit "sorted" = assert (List.sort compare [2;1] = [1;2])24.4 Property-based testing (QCheck)
let rev_involutive =
QCheck.Test.make ~count:1000 ~name:"rev twice"
QCheck.(list int) (fun l -> List.rev (List.rev l) = l)
let () = QCheck_runner.run_tests_main [ rev_involutive ]24.5 Cram tests (CLI testing)
$ myapp --version
1.0.024.6 Documentation with odoc
dune build @doc → _build/default/_doc/_html/index.html.
(** [clamp ~lo ~hi x] returns [x] bounded to [\[lo, hi\]].
{[
clamp ~lo:0 ~hi:10 15 = 10
]}
@raise Invalid_argument if [lo > hi]. *)
val clamp : lo:int -> hi:int -> int -> int24.7 Debugging techniques
Print debugging: Printf.eprintf, Format.eprintf "%a".
#trace in the toplevel: #trace fib;; fib 3;; Backtraces: OCAMLRUNPARAM=b./prog
ocamldebug (bytecode, supports time-travel): ocamlc -g, ocamldebug ./prog.
gdb/lldb on native code (OCaml 5 emits DWARF CFI).
Landmarks / perf / memtrace for profiling (see §40).
ppx_deriving.show to auto-generate printers for debugging.
🧪 Part II Exercises
Implement a binary search tree module with signature BST (insert, mem, remove, to_list, height).
Write a functor MakeCache (K : Hashtbl.HashedType) producing a memoising cache.
Build a bank account module with an abstract type where the balance can't go negative (return result).
Write a word-frequency counter reading a file, using Hashtbl, and printing the top 10 words.
Implement a priority queue (leftist heap) as a functor over ORDERED.
Write a CSV parser that handles quoted fields, returning (string list list, string) result.
Implement a stack-based RPN calculator using variants and exceptions.
Create a dune project with a library, an executable, and alcotest tests.
Convert an imperative bubble sort on arrays into a functional insertion sort on lists.
Write an interpreter for the expr type in §12.4 with error handling via result.