Как установить таймаут для тестов с OUnit?

У меня есть несколько тестов на бесконечные ленивые структуры, которые могут работать бесконечно, если протестированная функция не реализована правильно, но я не могу найти в документации по OUnit, как установить таймаут для тестов.

2 ответа

Решение

Я не думаю, что oUnit обеспечивает эту функциональность. Я помню, что мне пришлось делать это некоторое время назад, и это быстрый взлом, который я придумал:

let race seconds ~f =
  let ch = Event.new_channel () in
  let timeout = Thread.create (fun () ->
      Thread.delay seconds;
      `Time_out |> Event.send ch |> Event.sync
    ) () in
  let tf = Thread.create (fun () ->
      `Result (f ()) |> Event.send ch |> Event.sync) () in
  let res = ch |> Event.receive |> Event.sync in
  try
    Thread.kill timeout;
    Thread.kill tf;
    res
  with _ -> res

let () =
  let big_sum () =
    let arr = Array.init 1_000_000 (fun x -> x) in
    Array.fold_left (+) 0 arr in
  match race 0.0001 ~f:big_sum with
  | `Time_out -> print_endline "time to upgrade";
  | `Result x -> Printf.printf "sum is: %d\n" x

Это работало достаточно хорошо для моего случая использования, но я определенно не рекомендовал бы использовать это хотя бы потому, что race не будет работать так, как вы ожидаете, если ~f не выделяет и не звонит Thread.yield вручную.

Если вы используете OUnit2, должно работать следующее:

let tests = 
    "suite" >::: [OUnitTest.TestCase ( 
                    OUnitTest.Short,
                    (fun _ -> assert_equal 2 (1+1))
                  );
                  OUnitTest.TestCase (
                    OUnitTest.Long,
                    (fun _ -> assert_equal 4 (2+2))
                  )]

Тип test_length определяется как:

type test_length =
|   Immediate
|   Short
|   Long
|   Huge
|   Custom_length of float
Другие вопросы по тегам