Closed ergl closed 8 years ago
I don't have a really satisfying answer to this, but can offer a few suggestions:
inject
, declare several instances of the functor, say StrGSet
and IntGSet
;
then, instead of (*$< StrGSet
, write tests with explicit references to the module:(*$inject
module StrSet = Make(String)
module IntSet = Make(struct type t = int let compare=compare end)
*)
module Make(X : Set.OrderedType) = struct
module S = Set.Make(X)
let foo l =
let s = List.fold_right S.add l S.empty in
S.cardinal s = List.length (S.elements s)
(*$Q
Q.(list printable_string) StrSet.foo
Q.(list int) IntSet.foo
*)
end
Q.unit (fun () -> ...)
very strange. Are you sure you don't want a T
(unit) test rather than a Q
(random) test?Yes, it seems like defining several modules and testing those will be the least difficult option — the test doesn't have a header, but I can live with that. Being able use the foo, bar as x
idiom with different generators would be ideal though.
Regarding the weird Q.unit (fun () -> ..).
, I'm trying to test several properties about my functions, but I haven't got around to implement my own custom generator as it looks quite daunting. For now I'm using the module's make : unit -> t
constructor function to generate my values. For example:
(*$QR merge
Q.unit (fun () ->
let a = make () and
b = make () and
c = make ()
in
(merge a a) = a &&
(merge a b) = (merge b a) &&
(merge a (merge b c)) = (merge (merge a b) c))
*)
for writing a custom generator, it might look like this:
let gen : foo QCheck.Gen.t = fun rand -> ...
(* generate random values here using random state `rand` *)
let arb : foo QCheck.arbitrary = QCheck.make gen
(* the random generator + optional printers, shrinker. etc. *)
...
(* to use it *)
(*$Q
Q.(triple arb arb arb) (fun (a,b,c) -> ...)
*)
It is possible to add a printer, shrinker, etc. to the call to QCheck.make
.
Hi, I've been using this library for a few days and it seems really useful, but I'm wondering what is the best way to test a functor. The docs mention using injections to go around this.
Currently I'm doing this:
But I'm wondering if maybe there is a better way to go around this?
Now the test are coupled with whatever module you pass to the functor. My code only tests a particular implementation of
Make
withstrings
, but maybe the tests won't hold forint
, or for any other type.