Shrinking is one of the most critical components of property-based testing. It is the system by which a property-based testing framework can be told how to simplify failure cases enough to let us figure out precisely what the minimum reproducible case is. While finding complex obtuse cases is worthwhile, being able to reduce failing inputs to a simple counterexample truly is the killer feature.
When a large dataset faces a failure, it can be challenging to find the initial failure case due to irrelevant data. In this case, the framework can shrink data in the following ways:
On the other side, shrinking is not a good zero-point for some data types. These are shown below:
There are two ways to handle things that can be used to impact shrinking:
?SHRINK
?LETSHRINK
?SHRINK
Conceptually, ?SHRINK
is the simplest of the two macros that can be used to impact shrinking. It is best used to pick a custom zero-point toward which PropEr
will try to shrink data. The DefaultGenerator
will be used for all passing tests.
In Erlang, macro takes the form
?SHRINK(DefaultGenerator, [AlternativeGenerators])
.In Elixir, macro takes the form
shrink(default_generator, [alternative_generators])
.
?LETSHRINK
In PropEr
, we sometimes get stuck with generators that are creating huge data structures, take a long time to shrink, and often don’t give very interesting results back. Whenever this happens, we need the the ?LETSHRINK([Pattern, ...], [Generator, ...], Expression)
.
Free Resources