
Evan Laforge
QuickCheck seems to fit well when you have small input and output spaces, but complicated stuff in the middle, but still simple relations between the input and output. I think that's why data structures are so easy to QuickCheck. I suppose I should look around for more use of QuickCheck for non-data structures... the examples I've seen have been trivial stuff like 'reverse . reverse = id'.
I second this feeling... For example, I've never seen (I've not looked hard, though) Quickcheck's testing applied on graphs. Generating "interesting" (whatever that means for your particular problem) graphs doesn't seem to be a trivial test, even if it's a mere data structure... Does anyone know of such examples? Maybe genetic programming producing graphs is of relevance here (where generating candidate graphs have exactly the same problem). Also, I wonder how you guys do when you're trying to tests code using a lot of numbers (be them floating point or even integer). E.g., integers: A code doing addition and substraction of some sort. A property such as "X = (X add Y) sub Y" is easily falsifiable when the number of bits of your integer is too small for your numbers. E.g. floating point numbers: A code doing coordinate transformations of some sort. Properties akin to "roundtripping" can be easily formulated (e.g. "X = trfY_toX(trfX_toY(X))"), but they'll be falsified often due to lost bits in the mantissa. Replacing strict equality (almost always meaningless for floats) with approximate equality will work. However, definitions of such an approximate equality might vary (the immediate idea is to compare the difference of the two numbers with a small "epsilon", say 10^-9, but that will obviously not work if you numbers are around 10^-12...). And there are also, of course, overflows and underflows, and singularities (e.g. division by zero), non invertibility... So, in addition to defining the approximation (not always easy as I tried to "demonstrate" above) to be used in comparisons, one probably needs ad'hoc generators whose complexity might very well exceed that of the code one wants to test... So, do you have any "methodology" for such use cases? --Serge