I haven’t written any Scala in ages. Mostly I’m OK with this – there are still a few language features I miss from time to time, but nothing too serious.

One thing I do often miss though is Scalacheck. It’s really the nicest instance of Quickcheck style random testing I’ve seen (this is admittedly not based on a great deal of experience such libraries other than Quickcheck itself and some exceedingly half-assed ports).

One of its nice features is that as well as randomly generating test data, it also minimizes the examples it generates. So rather than generating really complicated examples as soon as it finds one that fails, it takes those examples and attempts to generate something simpler out of them.

I was thinking about this today and decided to have a play with putting something like this together in python. Rather than build a full testing setup I thought I’d instead just build the basic core algorithm and then figure out how to integrate this with py.test and similar later.

Enter hypothesis, a library for generating and minimizing data and using it to falsify hypotheses.

In [ 1 ] : from hypothesis import falsify In [ 2 ] : falsify ( lambda x , y , z: ( x + y ) + z == x + ( y +z ) , float , float , float ) Out [ 2 ] : ( 1.0 , 2.0507190744664223 , - 10.940188909437985 ) In [ 3 ] : falsify ( lambda x: sum ( x ) < 100 , [ int ] ) Out [ 3 ] : ( [ 6 , 29 , 65 ] , ) In [ 4 ] : falsify ( lambda x: sum ( x ) < 100 , [ int , float ] ) Out [ 4 ] : ( [ 18.0 , 82 ] , ) In [ 12 ] : falsify ( lambda x: "a" not in x , str ) Out [ 12 ] : ( 'a' , ) In [1]: from hypothesis import falsify In [2]: falsify(lambda x,y,z: (x + y) + z == x + (y +z), float,float,float) Out[2]: (1.0, 2.0507190744664223, -10.940188909437985) In [3]: falsify(lambda x: sum(x) < 100, [int]) Out[3]: ([6, 29, 65],) In [4]: falsify(lambda x: sum(x) < 100, [int,float]) Out[4]: ([18.0, 82],) In [12]: falsify(lambda x: "a" not in x, str) Out[12]: ('a',)

The current state of this is “working prototype”. It’s reasonably well tested, and the external interface to falsify is probably not going to change all that much, but the internals are currently terrible and liable to change almost entirely, but I’m reasonably happy with it as a proof of concept.