Heavily influenced by oUnit.
You may find this helpful if you want to
You could even use this library to test normal OCaml code, but in that case you're probably better off just using oUnit for the extra features it provides.
ocaml-webtest consists of two libraries:
This has no dependencies, and contains code for creating tests and suites.
This depends on
js_of_ocaml, and contains code used for running tests in a
Creating test suites
ocaml-webtest supports two kinds of test cases - synchronous and asynchronous.
Both kinds of test cases can use the assertion functions
assert_raises to check for expected behaviour.
Synchronous test cases are functions of type
unit -> unit, and in order to
pass should return cleanly without throwing an exception.
Some examples of simple synchronous test cases:
let sync_test1 () = Webtest.Suite.assert_equal (get_five ()) 5 let sync_test2 () = Webtest.Suite.assert_true (get_value ()) let sync_test3 () = Webtest.Suite.assert_raises MyExn (exception_thrower ())
Asynchronous test cases are functions of type
((unit -> unit) -> unit) -> unit. When run they are passed a wrapper function
which must be used to wrap any asynchronous code which should be triggered as
part of the test. In order to pass, an asynchronous test case should not only
return cleanly, it should also make sure that the wrapped code runs
successfully. Asynchronous test cases can be used to check that an event handler
An example of an asynchronous test case:
let async_test wrapper = let js_object = create_object () in js_object##onclose := Dom_html.handler (fun _ -> wrapper (fun () -> assert_true "Object has been closed" (is_closed js_object)); Js._false); js_object##close
If you don't need to perform any assertions in the asynchronous code but just
need to check that a handler fired, you can call the wrapper function with
Async.noop, which is just an alias for
fun () -> ().
Synchronous and asynchronous test cases can be combined into suites using the
>::: - for example:
open Webtest.Suite let suite = "suite" >::: [ "sync_test1" >:: sync_test1; "sync_test2" >:: sync_test2; "sync_test3" >:: sync_test3; "async_test" >:~ async_test; ]
Once you've created a suite, you can integrate it into an HTML document using
let () = Webtest_js.Runner.setup suite
webtest which exposes a simple
API for running the test suite.
webtest.runis a function with no arguments - calling it will run the test suite.
webtest.finishedis a boolean indicating whether the suite run has finished.
webtest.passedis a boolean indicating whether all the tests passed.
webtest.logcontains the log produced by running the tests.
A "known good" setup for automating browser tests (and what this repository uses for CI) is:
- Firefox 50
- Python 2.7 with version 3.3.0 of the Selenium bindings
- geckodriver 0.15.0
- Xvfb (optional, unless running on a headless machine)
For a more real-world example, see ocaml-webaudio.