In October I presented at GothamGo in NYC about what fuzzing is and how it can help you find bugs early in day to day development if you integrate it in your workflow. I specifically focused on Dmitry Vyukov's go-fuzz and provided an example of how I used it to find bugs in github.com/miekg/dns.
To fuzz a program means to feed it with randomly mutated inputs, in order to trigger unexpected behavior. Recent successful tools like afl-fuzz and go-fuzz use code instrumentation to detect interesting mutations that extend the code coverage.
For a long time fuzzing has been mostly used by security researchers hunting for exploitable memory bugs in unsafe languages, and that's a shame! Fuzz tests are as effective at triggering unexpected behavior and panics in Go programs as they are at finding security flaws in C. They not only find crashes, but can also be easily taught to detect states and results which should be impossible. go-fuzz helped find more than 100 bugs in the Go stdlib alone.
Fuzzing shouldn't be a one-off just like normal tests aren't. Fuzz tests should be first-class citizens of your test suite. They should be written by the developers, who know best what to test and where to hook. They should be committed to the tree for everyone to expand. They should be run regularly to detect regressions.
Finally, the corpus of fuzzed inputs they generate can be tremendously effective as a development tool. For example, automatically discovered corner cases can be used to compare two implementations or versions of the same functionality.
I explain what results to seek, how to write and maintain go-fuzz tests that go beyond crash detection, and show a few examples and results in widely used libraries.