Page
Library
Module
Module type
Parameter
Class
Class type
Source
Windtrap runs unit, property, stateful and expect tests from one flat interface, with coverage and mutation testing in the companion ppx. A suite is an ordinary executable that dune runtest builds and runs.
open Windtrap
let basics =
group "basics"
[
test "evicts the oldest entry when full" (fun () ->
let c = Lru.create 2 in
List.iter (fun k -> Lru.add c k k) [ 1; 2; 3 ];
equal (option int) None (Lru.find c 1));
test "lists its keys, most recent first" (fun () ->
let c = Lru.create 3 in
List.iter (fun k -> Lru.add c k k) [ 1; 2; 3 ];
ignore (Lru.find c 1);
expect (Lru.to_string c) @@ __POS_OF__ {|1 3 2|});
]
let bounded =
prop "never holds more than its capacity" Gen.(list int) (fun keys ->
let c = Lru.create 3 in
List.iter (fun k -> Lru.add c k k) keys;
at_most int ~than:3 (Lru.size c))
let () = exit (run "lru" [ basics; bounded ])A run with nothing to report prints one line:
$ dune runtest
mylib: 3 passed in 1.0ms (seed s1:b02192cebcec40d2).test and group declare a suite, and run runs it. Assertions such as equal, less, contains, raises and require_some take a witness, for example int or list string, and a failure prints the values it compared.
test "splits on commas" (fun () ->
equal (list string) [ "a"; "b" ] (String.split_on_char ',' "a,b"))prop checks a law over values generated with Gen. A failing input is reduced to a smaller one that still fails. Law states textbook laws, such as an involution or a round trip, and a failure names each term.
prop "rev is an involution" Gen.(list int) (Law.involutive (list int) List.rev)stateful runs generated programs of calls on a system and on a reference, such as a model of its state or another implementation, and compares what each call returns or raises. A failing program is reduced to a shorter one and printed as the calls that ran. With ~domains:2, the middle of each program runs on two domains at once, and the test fails when no order of the calls explains the results.
command "pop" (queue ^-> returns int) Model.pop Bounded_queue.popexpect compares a string with a literal in the test's source, and expect_file with a file. ppx_windtrap provides let%expect_test and [%expect]. dune promote accepts a change.
expect (Printf.sprintf "%d items" (List.length cart)) @@ __POS_OF__ {|3 items|}ppx_windtrap.coverage instruments a library, and windtrap coverage reports the expressions that the tests did not run.
dune runtest --instrument-with ppx_windtrap.coverage
dune exec windtrap -- coverageppx_windtrap.mutate compiles mutants of a library, small changes such as >= into >, into its test executables. --mutate runs the tests on each mutant and reports the mutants that no test fails on.
dune exec --instrument-with ppx_windtrap.mutate test/test_calc.exe -- --mutate opam install windtrap
opam install ppx_windtrap # expect tests, coverage, mutation testingThe manual, doc/manual/, has one page per need:
How-to:
expect, expect_file, let%expect_test.dune runtest and CI.lib/windtrap.mli, and ppx/ppx_windtrap.mli for the inline test forms.Questions are welcome on the OCaml forum.
examples/ holds the project of each manual page, run by dune runtest; its README lists them.
Windtrap builds on ideas and code from several OCaml projects:
THIRD_PARTY_LICENSES.md holds the notices of the code derived from them.