QCheck2.Shrink
Shrinking helper functions.
Shrinking is used to reduce the size of a counter-example. It tries to make the counter-example smaller by decreasing it, or removing elements, until the property to test holds again; then it returns the smallest value that still made the test fail.
This is meant to help developers find a simpler counter-example to ease investigation and find more easily the root cause (be it in the tested code or in the test).
This module exposes helper functions that one can reuse in combination with Gen.make_primitive
to craft custom primitive generators (not by composing other generators). The vast majority of use cases will probably not need this module.
module type Number = sig ... end
Util module representing a number type, used for ad hoc polymorphism of some functions like number_towards
.
Shrink a number by edging towards a destination.
The destination is always the first value for optimal shrinking.
let int64_towards_list destination x = List.of_seq @@
Gen.number_towards (module Int64) ~destination x
in
assert (int64_towards_list 0L 100L =
[0L; 50L; 75L; 88L; 94L; 97L; 99L]);
assert (int64_towards_list 500L 1000L =
[500L; 750L; 875L; 938L; 969L; 985L; 993L; 997L; 999L]);
assert (int64_towards_list (-50L) (-26L) =
[-50L; -38L; -32L; -29L; -28L; -27L])
This generic function is exposed to let users reuse this shrinking technique for their custom number types. More specialized, convenient functions are provided below, e.g. int_towards
.
val int_towards : int -> int -> int Seq.t
number_towards
specialized to int
.
val int32_towards : int32 -> int32 -> int32 Seq.t
number_towards
specialized to int32
.
val int64_towards : int64 -> int64 -> int64 Seq.t
number_towards
specialized to int64
.
val float_towards : float -> float -> float Seq.t
number_towards
specialized to float
.
There are various ways to shrink a float:
This implementation, as it relies on the generic number_towards
function, tries to get as close as possible to the destination, e.g. the last value of Gen.float_towards 50 100
may be 99.9969482421875
(or a similar value).
val int_aggressive_towards : int -> int -> int Seq.t
int_agressive_towards destination n
gives all integers from destination
to n
(excluded).
Be careful about time and memory as the resulting list can be huge
val int_aggressive : int -> int Seq.t