Comment by klntsky
18 hours ago
It seems to only implement a half of QuickCheck idea, because there is no counterexample shrinking. Good effort though! I wonder how hard would it be to derive generators for any custom types in python - probably not too hard, because types are just values
Shrinking is by far the most important and impressive part of Hypothesis. Compared to how good it is in Hypothesis, it might as well not exist in QuickCheck.
Proptest in Rust is mostly there but has many more issues with monadic bind than Hypothesis does (I wrote about this in https://sunshowers.io/posts/monads-through-pbt/).
Python's Hypothesis has some very clever features to deal with shrinking past a monadic bind.
If I remember right, it basically uses a binary 'tape' of random decisions. Shrinking is expressed as manipulations of that tape. Your generators (implicitly) define a projection from that tape to your desired types. Shrinking an early part of the tape, leave the later sub-generators to try and re-use the later parts of the tape.
That's not guaranteed to work. But it doesn't have to work reliably for every shrink operation the library tries! It's sufficient, if you merely have a good-enough-chance to recover enough of the previous structure to trigger the bug again.
> Shrinking is expressed as manipulations of that tape.
How do you do that in general? I can't find any documentation on that.
1 reply →
I've always wondered if there could be a small machine learning model trained on shrinking.
1 reply →
> because there is no counterexample shrinking
Hypothesis does shrink the examples, though.
And Hypothesis is miles ahead of QuickCheck in how it handles shrinking! Not only does it shrink automatically, it has no problem preserving invariants from generation in your shrinking; like only prime numbers or only strings that begin with a vowel etc.
QuickCheck also shrinks automatically and preserves invariants though?
2 replies →
The way it does counterexample shrinking is the most clever part of Hypothesis.
Do you have a reference where it is explained? It's not part of the docs as far as I can tell
You might try this blog entry (or other blog entries that talk about shrinking):
https://hypothesis.works/articles/how-hypothesis-works/