I am happy to announce a first release of Popper — an OCaml testing library for writing simple unit tests as well as property-based tests, using a uniform API.
A few things that distinguishes Popper from other property-based testing libraries:
Generic shrinking — when a property-based test fails, the test function attempts to shrink the sample data. This works for any data type.
Any invariants used when constructing samples for property-based tests are also respected when shrinking.
There is a ppx for automatically deriving sample functions (generators in QuickCheck style libs) for custom data types.
The library also supports bundling and nesting tests arbitrarily, colorful output inspired by Alcotest, logging facilities and timing info.
That seems quite impressive, congratulations. A suggestion would be to take some existing works based on property-based testing (for example, Jan’s work) and adapt it to your framework to serve as examples/show cases.
At a glance I didn’t see any public shrinking API, what do you use underneath? Seq.t? Also, is there a way to make a custom Sample.t from a generator and a shrinker?
In QCheck we’ve been working on a similar track with thesePRs, so it’s interesting to see the convergence.
Thanks, I can take a look at these examples here. Or, did you have some specific repo in mind?
At a glance I didn’t see any public shrinking API, what do you use underneath? Seq.t ? Also, is there a way to make a custom Sample.t from a generator and a shrinker?
I don’t (yet) expose an API for obtaining a sequence of shrunken values. In general the design is different from QuickCheck style libraries in that shrinking is only performed on the input sequence fed to the generators/samplers. This strategy is inspired by the rather popular Python library Hypothesis. Here are some more details on how it work in Popper.
There is no coupling of generators/shrinkers in the same data-structure. So far I’ve been focusing on getting generic shrinking to work reasonably well (and fast) but it would be straight forward to extend the library to also allow overriding with custom shrinkers when need be.
In QCheck we’ve been working on a similar track with thesePRs, so it’s interesting to see the convergence.
Nice, noticed you landed that for QCheck2. I’m also curious to compare the strategies since your underlying design is different.