liveBook · Manning

Fuzzing

As explained in Go in Action, Second Edition

Fuzzing automatically tests software with generated or mutated inputs to find failures and unexpected behavior.

Fuzzing proactively tests input-driven code by expanding valid examples into generated cases, exposing edge conditions that ordinary tests may miss. Go includes fuzz testing in its standard testing library. section 8.0 section 8.7.2

A Go fuzz test typically:

  • Defines a function whose name begins with Fuzz and accepts *testing.F. section 8.7.2
  • Adds seed examples to a corpus with f.Add. section 8.7.2
  • Runs the target with generated strings, runes, or other expanded inputs and compares the result against an expected behavior. section 8.7.2
  • Uses go test -fuzz=. with a time limit, then preserves minimized failing inputs for reproduction. section 8.7.2

Finding a Unicode bug

A fuzz test compared a custom Contains function with strings.Contains across seeded cases such as ordinary words, empty strings, and rune values. Fuzzing found a failure caused by converting the input string to []byte, which mishandled a multibyte character. Iterating over the string as runes fixed the defect; the minimized input could then be rerun as a regression case. section 8.7.2

Listing 8.38 xstrings_test.go: Fuzz contains function
func FuzzFindInString(f *testing.F) {
	cases := []struct { #1
		word string
		char rune
	}{
		{
			word: "hello world",
			char: 'e',
		},
		{
			word: "goodbye",
			char: 'e',
		},
		{
			word: "",
			char: 'o',
		},
		{
			word: "a longer example",
			char: 'z',
		},
	}
	for _, ca := range cases { #2
		f.Add(ca.word, ca.char)
	}
	f.Fuzz(func(t *testing.T, in string, r rune) { #3
		contains := xstring.Contains(in, r)
		if strings.Contains(in, string(r)) != contains { #4
			t.Errorf("failed to find '%b' in %s", r, in)
		}
	})
}

Shows the seed corpus, f.Add calls, fuzz callback, and comparison against strings.Contains. section 8.7.2

How Go in Action, Second Edition covers it

How deep it goes
Explains corpus setup, fuzz callbacks, execution commands, failure minimization, and a Unicode bug fix.
Examples
Tests a string Contains function with words, empty strings, runes, generated inputs, and minimized Unicode failures.
What it assumes
Builds on functions, test files, go test, expected behavior, and a set of valid test parameters.
What you can do after
Diagnose/debug with it by discovering, minimizing, reproducing, and fixing input-dependent failures.
How it connects
Connects fuzz testing with unit testing, benchmark testing, test coverage, corpora, and regression testing.

Also explained in

Compare how 7 books explain fuzzing →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Go in Action, Second Edition. The section links point to the parts of the book it draws on.