Haskell has the nice property that the type signature for a piece of code sometimes tells you what that code does. And that got me thinking... can you construct tests based on type signatures?
Consider, for example, a module such as Data.Map
. It defines a data type and several functions which operate on that type. Looking only that the type signatures, it should be possible [in principle] to figure out all possible ways of constructing Map
values. And by that I mean algorithmically possible - it ought to be possible to write some program that takes the interface to your module and figures out all possible function calls you could make against it.
Now, there are those who feel that a well-written test suite can be seen as the "specification" of what a library is supposed to do. Obviously the human that wrote the code knows what they're trying to do, and the machine doesn't. But the machine should be able to work out what it's possible ask for, given the type signatures that you've provided.
As a more specific case, suppose there is some set of invariants that are supposed to apply to all possible Map
values. (E.g., null m == (size m == 0)
, or perhaps an internal sanity-check function should always return true.) One might imagine writing a test framework, handing it the module, and saying "a value of type Map X Y
should always satisfy these invariants", and let the test framework go off and try to execute every possible combination of the functions you've provided to produce maps and check that they satisfy all the conditions. If not, it tells you what condition is violated and the expression needed to construct this invalid value.
My question is, does this sort of approach sound tractable? Desirable? Interesting? How would you approach solving a problem like this? Djinn seems to already know how to construct values of specified types given preexisting functions and constants, so trying to come up with multiple expressions having a given type doesn't sound too hard. What kind of heuristics might one apply to attempt to get good code coverage? (Obviously analysing code rather than just types is drastically harder... Rice's theorem lurks in wait.)
(Note that I'm not suggesting that this kind of machine checking should replace hand-written test code. The idea is more to augment it; perhaps in harder cases, the machine could cough up possible expressions, and then ask a human what the "right" answer ought to be. This can then be recorded as a new test case, to be run whenever the test suite runs.)