Permalink
Browse files

Random tests can now return the smallest failure value.

eg: (*$Q of_list & ~count:1000000  ~small:(Some List.length) will return the smallest list, if any, that causes the test to fail, among the count executions. Idea courtesy of the issue #242 debacle.
  • Loading branch information...
1 parent ee93878 commit bda3776462d1ad7616823e7ba592eea987062f59 @vincent-hugot vincent-hugot committed Feb 4, 2012
Showing with 27 additions and 4 deletions.
  1. +1 −1 qtest/core.ml
  2. +25 −2 qtest/quickcheck.ml
  3. +1 −1 src/batSet.ml
View
@@ -193,7 +193,7 @@ let test_handle_of_uid uid = "_test_" ^ soi uid
(** get a pretty, user-friendly version of the code wrt. whitespace *)
let prettify s =
if String.contains s '\n'
- then (* multi-line : as-is *) "\n\n" ^ s
+ then (* multi-line : as-is *) "\n\n" ^ s ^ "\n\n"
else (* single-line: normalise *) trim (normalise s)
View
@@ -182,11 +182,34 @@ let rec laws iter gen func =
else laws (iter-1) gen func
with _ -> Some input
+(** like [laws], but executes all tests anyway and returns optionally the
+ smallest failure-causing input, wrt. some measure *)
+let rec laws_smallest measure iter gen func =
+ let return = ref None in
+ let register input =
+ match !return with
+ | None ->
+ return := Some input
+ | Some x ->
+ if measure input < measure x then
+ return := Some input
+ in
+ for i = 1 to iter do
+ let input = gen () in
+ try if not (func input) then register input
+ with _ -> register input
+ done;
+ !return
+
+
let default_count = 100
(** Like laws, but throws an exception instead of returning an option. *)
-let laws_exn ?(count=default_count) name (gen,pp) func =
- match laws count gen func with
+let laws_exn ?(small=None) ?(count=default_count) name (gen,pp) func =
+ let result = match small with
+ | None -> laws count gen func
+ | Some measure -> laws_smallest measure count gen func
+ in match result with
| None -> ()
| Some i -> failwith (Printf.sprintf "law %s failed for %s" name (pp i))
View
@@ -658,7 +658,7 @@ let of_enum_cmp ~cmp t =
let of_list l = List.fold_left (fun a x -> add x a) empty l
-(*$Q of_list
+(*$Q of_list & ~count:1000000 ~small:(Some List.length)
(Q.list Q.int) (fun l -> let xs = List.map (fun i -> i mod 5, i) l in \
let s1 = of_list xs |> enum |> List.of_enum in \
let s2 = List.sort Pervasives.compare xs in \

0 comments on commit bda3776

Please sign in to comment.