So should you use quickcheck? Yes you should, but you should also keep an eye on things like code coverage and branch coverage because it is possible that you have that one very strange corner case that will never be found this way.

Or you should analyse your code for complicated data structures (e.g. I would call “196913” a “complicated” Int) and either:

Has anyone been able to use QuickCheck for larger properties on more complicated scenarios? I see how it can replace unit tests, but I have a hard time imagining the “arbitrary crawling” successfully finding bugs in places like billing code in a larger functional test.

I suppose the answer is to break things up until they are testable though….

Depends on the language you’re in. Quviq, which sells their own version of QuickCheck for Erlang, has support for state machines, which many integrations can be boiled down to. The way it works is you define, in your test, a model for what the state machine does and commands to perform state transitions, and then checks invariants after each command. It then does shrinking on the commands to give the minimal number of commands that break the invariant.