проблемой (прошу палками не забивать, я OCaml практически не трогал до этого момента):
open OUnit2
let create_test_case (type a b) (f: a -> b) name (expect : b) (args : a) =
name >:: (fun _ -> assert_equal ~printer:(Printf.sprintf "%s") expect (f args))
let create_test_suite name cases =
name ^ " test suite" >::: cases
(* Interface for task tests. *)
module type Task = sig
val test_suite : test
end
(* Generic test runner. *)
module TaskRunner = struct
let run tasks =
List.iter (fun (module T : Task) -> run_test_tt_main T.test_suite) tasks
end
(* Write a function [last : 'a list -> 'a option] that returns the last element of a list. *)
module Task01 : Task = struct
let rec last = function
| [] -> None
| [x] -> Some x
| _ :: t -> last t
let test_case = create_test_case last
let test_suite = create_test_suite "first"
[
test_case "no elements" None ([]);
test_case "single element" (Some 42) ([42]);
test_case "multiple elements" (Some 5) ([1; 2; 3; 4; 5]);
]
end
(* ... *)
let _ =
TaskRunner.run
[
(module Task01); (module Task02); (module Task03); (module Task04); (module Task05);
(module Task06); (module Task07); (module Task08); (module Task09); (module Task10);
]
Все круто и классно - работает. Как видно в TaskRunner.run, на самом деле модулей у меня куда больше, и есть проблема: когда какой-нибудь test_case падает - я получаю "not equal" и ничего более. Мне бы хотелось увидеть какой-нибудь diff, хотя бы. Из моих попыток нагуглить - я выяснил, что для каждого типа нужно писать либо свой string_of_t вариант, либо использовать ppx_* для автогенерации форматирования. В моем случае, используются простые списки из примитивных типов. Неужели язык не предоставляет для них форматтеров? Извините, если кого-то религиозно (в плане языка) задену, но в Rust'е мне достаточно сделать assert_eq!(a, b) и оно мне все по феншую разложит, ибо там под капотом у почти всех типов стандартной библиотеки реализованы Eq и ToString трейты для удобства.
нет, в окамле такое не реализовано по-умолчанию
OUnit2 давно не использовал, но в Alcotest есть реализация testable для всех основных типов (testable реализует отображение и сравнение для типа) и возможность их комбинирования типа list option int. Но да, их все равно нужно явно указывать.
Обсуждают сегодня