foretspaisibles / broken

Extensible testsuite framework for OCaml
http://michipili.github.io/broken
Other
11 stars 1 forks source link

Testing with Async/Lwt #10

Open rgrinberg opened 8 years ago

rgrinberg commented 8 years ago

The number one deficiency I find in all OCaml unit testing frameworks today is the lack of integration with Async/Lwt. To me this means two things:

1) Having tests that return a Lwt.t (or a Deferred.t)

2) Test runner that is aware of the lwt/async scheduler

Would you recommend to use broken to test Lwt code? If so, how should one do it?

foretspaisibles commented 8 years ago

The approach I used until now is to define tests running thread(s) using the main scheduler, as in the following example:

let assert_process_status ident ?expected_failure f status =
  let broken_f () =
    let t =
      Lwt.catch
        (fun () -> f () >|= fun _ -> WEXITED(0))
        (function
          | Error(_, got, _) -> Lwt.return got
          | exn -> Lwt.fail exn)
    in
    Lwt_main.run t
  in
  assert_equal ident ?expected_failure
    ~printer:pp_print_process_status
    broken_f () status

This excerpt from Rashell source code defines a new assert_* function (a function returning test cases) which constructs an asynchronous value of type 'a Lwt.t which is then passed to Lwt_main.run.

You can see this function and its siblings in action in the Rashell testsuite, for instance the TestPosix module.

Could you use a similar strategy for your tests? If you need special support for your tests, we might implement it in broken.

rgrinberg commented 8 years ago

This is a decent work around for lwt but unfortunately async doesn't have the equivalent of Lwt_main.run

foretspaisibles commented 8 years ago

I have little experience with async but if I understand correctly, it would be enough to write a an async_main_run function which takes a function performing a deferred computation and applies it on an argument, taking care of catching exceptions thrown by the computation – which implies installing these exception handlers. Am I correct?