I'd like to come up with a motivating example or code challenge for fuzz testing and/or property-based testing.
What I'm looking for is a concise situation where such testing is maximally critical/necessary.
For example, ideally it would take enough fuzz runs that a human would be unlikely to discover the bug by manually trying random unit tests or relying on intuition to come up with edge cases.
Bonus if:
- in TypeScript (but not a big deal; I can translate)
- an example from real/historical software
I tried asking ChatGPT but the bug was too obvious. I also tried a bit of Googling and found this, but it's still quite obvious and probably also reveals itself after a few unit tests. I also considered making some kind of broken lookup table (inspired by Pentium FDIV bug) but I couldn't figure out how to make it so that you can't trivially solve it by just computing the correct lookup table and comparing it.
One in my opinion convincing and still easy-to-understand example is prime factorization. Look at the blog article on property-driven development of such an algorithm.
Full disclosure: I'm the author of the article and main committer of the used PBT library.
Consider the implementation (sorry it's Java) as it resulted after a few steps of TDD using properties:
From an algorithmic standpoint
factorizeworks alright. Some of the failings - e.g. handling large numbers, potential integer overflows - are only discovered when you set it under stress with a generic property:If you start increasing
maxbeyond 1_000_000 and towardsInteger.MAX_VALUErange the algorithm will run for a very long time or not finish at all. Those failing properties lead to changes of the algorithm to handle factorization for the full range of integers. An implementation running fast up to the maximum integer value is e.g.:Before I learned about PBT, I tended to not test such things; now it comes naturally.