go/testing

Fuzzing in Go is a testing technique to find bugs, crashes or unexpected behavior in code by passing in automatically generated, semi-random inputs to a function.

It’s useful for,

  • Finding security vulnerabilities (e.g., panics, crashes, memory corruption).
  • Testing how functions behave with malformed, edge-case, or unexpected input.
package fuzzdemo
 
import "testing"
 
func Reverse(s string) string {
	runes := []rune(s)
	n := len(runes)
	for i := 0; i < n/2; i++ {
		runes[i], runes[n-1-i] = runes[n-1-i], runes[i]
	}
	return string(runes)
}
 
func FuzzReverse(f *testing.F) {
	// Seed corpus
	f.Add("hello")
	f.Add("123")
	f.Add("😀😃😄")
 
	f.Fuzz(func(t *testing.T, input string) {
		rev := Reverse(input)
		doubleRev := Reverse(rev)
		if input != doubleRev {
			t.Errorf("expected %q, got %q", input, doubleRev)
		}
	})
}
go test -fuzz=Fuzz

You’re telling Go to fuzz indefinitely until,
The Go fuzzing engine is designed to keep running:

  • Continuously generating new inputs
  • Trying to find edge cases or crashes
  • Minimizing inputs that cause panics or test failures

It only stops if:

  • A bug/panic is found
  • You manually interrupt it (e.g., with Ctrl+C)
  • You provide a timeout or fuzzing limit

👉 Go’s native fuzzing only supports certain types directly:

  • string, []byte, int, bool, float64, etc.